In order to wrap up our marketing page, I want to add authentication because the marketing or landing page is going to show different things and different labels in the buttons depending whether the user is logged in or not. So for authentication we're going to be using Clerk so we can add it super quickly inside of our app. So go ahead and create an account on Clerk and once you're in you can click new application or you are immediately gonna get prompted with a screen like this. So I'm gonna zoom in a bit so we can see what we're doing. I'm gonna call my app Lingo.
I'm gonna enable the email and Google. If you want to you can go ahead and play around with all of these other amazing providers that Clerk offers. Go ahead and click create an application and that should redirect you to the dashboard of your new app. So the first thing we have to do is copy this environment keys. So let's go ahead and do the following.
We're gonna create a new environment file and for that I want to go to .gitignore and I want to find where we already have .environment.local and I'm going to add .environment itself. So let's go ahead and save that file and now create .environment and paste those two keys inside. So next public clerk publishable key and clerk secret key. After you've done that, make sure Next.js is selected here and click continue in the docs. So we're gonna be using the app router.
So that's the type of instructions we are going to follow from this documentation. First things first, let's install the Next.js package for Qlrk. So head inside of your terminal here. I'm going to go ahead and use this separate one that I have. I'm gonna do npm install clerk-nextjs and after this has finished installing we already added the environment variables so we can skip step 2 and instead we can go and add the clerk provider inside of our layout file.
So let's go ahead and find that in the app folder layout and let's just wrap everything inside but before we do that we have to add the import clerk provider from clerk-next.js. So I'm gonna add the clerk provider very simply like this and indent the entire thing. Once we've added clerk provider let's go ahead and add the middleware. So I'm going to copy this boilerplate here. Actually let's copy the lower one so we have the matcher.
So I'm gonna copy this, the second one, and be careful with the naming of this file. So it needs to be created in the root of your application outside of any folder. So middleware.ts and make sure you don't misspell it because just like page and layout middleware is a reserved keyword. So I'm going to paste this inside and in here you have the basic layout. So I'm going to go ahead and remove the ignored routes because we're not going to need them.
And for the public routes, we can go ahead and add a slash. So the only public route we are going to allow is our landing page. So if I leave an empty array here and if I go inside of my localhost here and refresh, I'm redirected to the login page, right? But if I add the slash inside of the public routes array and then go back to my localhost 3000. There we go.
I can now see the header component. Great! So that is it for authentication. So just like that we added authentication without any problems. Later we're gonna add the user button but before we do that we're gonna go ahead and actually use some other clerk components.
So let's head back inside of our clerk, sorry inside of our app folder marketing header component here and let's start styling this a bit. So I'm gonna give this a div and I'm gonna give it a class name of large, max width of screen lg, mx auto, flex, items center, justify between, let me just remove this xss letter which I wrote, so justify between, and height all. So what does this do? Let's give it the background color of red 500 so we can see it more clearly here. So you can see that at one point this red block stops expanding.
You can see that by zooming out a lot in your application. But if you zoom in you can see that at certain point it will always go as much as the screen is, right? Excluding the padding which we've added. So what we've done here, these two, these two classes here. So on large devices, we use the max width to be large screen, meaning up to this breakpoint and then we give it an MX auto, right?
So on large devices it's not gonna go and expand all the way. So it's not like we're gonna see our logo here. We're only gonna expand up to this point because it's just nicer for it to look that way. Great, now let's go ahead and prepare the area for our logo here. So I'm gonna go ahead and create a div here.
I'm gonna give it a class name of padding top 8, pl4, padding bottom of 7, flex item center and gap x3. Now in here I'm gonna go ahead and add an image component. So import that from next slash image and now in you can either use any logo you want for your app or if you want the exact one that I'm using, let's go ahead inside of my repository. You can find that using the link in the description. Go inside of the public folder and inside of here you can find all of my images and all of my sounds.
So go ahead and find the mascot. So I'm gonna go ahead and find the mascot right here and I'm going to download it. If you're wondering where I got this from, it is from Kene Game assets. So if you want to, I'm going to leave the link in the description for this as well. This is literally thousands of completely free game assets.
If you want to, you can donate. I highly encourage you to do so. I did so myself because I am just amazed by the amount of content provided by Kenny here completely for free and I found this to be the perfect design style for our Duolingo app. So this is where I found some 2D assets, specifically this shape characters, which I've then used to create our mascot. So you can either create your own, you can use any other logo you want, or you can simply download the file from my GitHub and then just add it to your public folder.
There we go, mascot.svg. So let's go ahead and just close these things. Let me go back here. I'm going to go inside of my header component where we left off And now let's add a source of slash mascot.svg for this image and let's give it a height of 40 and let's give it a width of 40. And I'm going to give it an alt of mascot.
And let's also remove this background red 500 from our wrapping div because we no longer need that. We use that only to demonstrate what we are doing with our classes. And below the image add an h1 element which will simply render the name of our app lingo. And in here give it a text of 2xl, font extra bold and let's give it a text green 600 and tracking white. And let's not misspell tracking.
There we go. So we have our logo here in the corner great and now what I want to do is I want to go outside of this div which is wrapping my logo and I'm gonna add a clerk loading from clerk slash next JS so make sure you import this and inside of here I'm very simply going to render a loader from Lucid React. We have Lucid React already installed because Shazam UI initialization did that for us. So let's go ahead and give this loader a class name of height 5 width 5 text muted foreground which will give it a gray color and animate dash spin so now if you refresh for a second you should see a little spinner here in the corner indicating that we are checking whether we are signed in or not. Great, so we have handled the loading status and now let's do clerk loaded from clerk nextjs as well.
So let me just prepare this imports like this. Inside of clerk loaded I'm gonna check for signed in status again from clerk slash next.js so we can import that as well. And, sorry, not sign in, signed in. And let's also do signed out. So these two components, and then let's do sign in button.
And let's do it like that. So instead of using sign in, we're going to use the status signed in here. And all I'm going to render if we are signed in is the user button from clerk slash next.js. Notice how I also have this import for their beta version so Clerc is going to get updated soon but don't worry this implementation that we are doing in this tutorial will be supported for a long time but if you want to you can already explore the future beta. You can see that it has all the existing components, which I'm using in this tutorial anyway.
But I recommend that you follow this exactly as I'm doing. If you can simply import it from Clark Next.js, go ahead and do that. So UserButton is actually a self-closing component. So let's go ahead and make sure you import user button, signed in, clerk loading and clerk loaded. So right now you should not be seeing anything because we are not logged in.
We have not done that part yet. So then inside of clerk loaded go ahead and add if we are signed out which we already have imported and in here we're gonna add a sign in button component which we also have from our Next.js here. And go ahead and give it a mode of model. And let's give it after sign in URL to go to slash learn and after sign up to go to slash learn as well so regardless if we log in or create an account and inside we're going to use our button which we've created and styled in the previous chapter so let's go ahead and write inside login I'm going to give it a size of large and variant of ghost. There we go.
So now we should have a login button in the corner which should open the login model from Qlerk without redirecting the user. Great! So now we are done with the header component. What I want to do next is I want to, well first let's actually log in right so we can demonstrate this user button because there is one thing missing from this user button which is a prop after sign out whoops after sign out URL simply go back to slash and save this and refresh. So I'm gonna go ahead and log in so we can demonstrate the user button.
So after you've been logged in you're gonna get redirected to this 404 page because we told it to do that but we have not yet implemented that page. And there we go. Now in here you have the user button and you can use it to log out. Now let's go ahead and create the middle content in here, which is located inside of page.tsx itself. So for that we're going to need another image from here.
So let's go ahead and find the hero.svg inside of my public folder. So the same place you found this or of course you can use your own if that is what you prefer. There we go. So this is our hero image also thanks to Kene Game Assets. So let's go ahead and drag and drop that inside of our public folder.
There we go. And now let's go back inside of page.tsx here. Let's give this div a class name of Max with 998 pixels, sorry, 988 pixels, mx-alto, flex-1, full-width, flex, flex-col, on large flex is row so they are next to each other So we are automatically going to make this responsive. And then we're going to go ahead and give this an item's center. And justify center.
Let's give it a padding of 4 and a gap of 2. And now let's create a container which is going to hold our image component. So this container is going to have a class name of relative, width is going to be 240 pixels, Height is going to be 240 pixels as well. And on the large devices, width is gonna be 424 pixels. And on large, height is gonna be 424 pixels as well.
So these are obviously values which I have defined while working on the app that they look the best. So I'm also adding a margin bottom of 8 on mobile devices because on mobile they're going to be one above another and on large devices they're going to be next to each other. This image and our next component which we are going to do. So no need for margin bottom here. Let's give this image a source of slash hero.svg.
Let's give it a fill property and an alt of hero and of course we have to import the image from next slash image and there we go you can see how now it's here in the middle but when I expand you can see how it gets bigger So let's go ahead and add the next element to it now. So outside of this, let's go ahead and create a new div with a class name of flex-flex-col-item-center-gap-y8. And then in here let's add an h1 element. Learn, practice, and master new languages with Lingo. Let's give this H1 element a class name of TextExtraLarge.
On large devices, text is going to be 3XL, font is going to be bold, and text is going to be Neutral 600. Let's give it a max width of 480 pixels and text center. There we go. And now outside of h1 element I want to create special cases on whether we are logged in or not. So let's add our clerk loading from clerk next.js.
Inside of here we are going to render a loader from Lucid React. So let's give this a class name of height 5 width 5 text muted foreground and animate spin. So make sure you have added Clerk loading from Clerk Next.js, loader from Lucid React and image from NextImage and we're also gonna need this button which I have here from before. So now if you refresh you can see the same way as we have in our header. We now have a little spinner here.
And then if Clerk has loaded, so clerk loaded component from clerk nextjs make sure you add that to your imports we're going to do the status for signed out from clerk nextjs and we're gonna do signed in from clerk nextjs so again make sure you've added clerk loaded, clerk loading, signed in and signed out all from Clerk Next.js So inside of the signed out we're gonna go ahead and add the sign up button from clerk next.js and inside we're gonna render our button component which will say get started. So let's go ahead and give this a size of large, variant of secondary and class name with full. So again, make sure you added sign up button import from clark-next.js and let's give this sign up button a mode of model, after sign in to go to slash learn and same for after sign up. There we go and then so this is inside of signed out so Let's copy this sign up button again, paste it below and change this to be a primary outline button which will say I already have an account. There we go.
And this is going to be sign in button this time from Clark Next.js because the user using this is trying to log in. Whereas this get started is sign up. So make sure you have both sign in and sign up button and for this that we just copy-paste you should be using the sign in button. So now if you log out for example, there we go, you should be seeing get started and I already have an account. So let's go ahead inside of the signed in here and what we're going to do here is simply add a button component and write continue learning and we can add a link component from next slash link give it an hrep of slash learn give this button a size of large, variant of secondary, class name with full and as child prop is important because we're using the link component as a child here.
So make sure you imported the link from next slash link and now if you go ahead and try and log in. So I'm gonna click here I already have an account and let me go ahead and log in. And now if I go back to localhost 3000, there we go. It says continue learning. Great.
So we've done the basic landing page here. We're gonna go ahead and style it even better and we're going to wrap it up with our footer component in the next chapter. And then we can go ahead and start creating our database and slowly start creating the initial inner interface. Great, great job!