Introduction
This article will include additional context on what I learned as I added Clerk to Frontend Dot Dev, a Next.js App Router project. The documentation is pretty straightforward, but I found some steps needing more explanation, specifally around my use case.
The Advantages of Using Clerk
Honestly, I didn't want to spend months building my auth system. I wanted to focus on building the core features of my application. I also wanted to use a third party auth solution that would allow me to customize the user experience to match my brand. Clerk provides all of this and more. The built-in best practices in their <SignIn/>
and <UserProfile/>
components are so comprehensive. I was able to get up and running in less than an hour.
Integrate Clerk into a Next.js App Router Project
-
Create a Clerk account. You can do this by going to clerk.dev and clicking on the "Sign Up" button.
-
Install Clerk in your project. The
@clerk/nextjs
package provides the necessary tools and components to integrate Clerk's services into a Next.js application.
- Set environment keys in
.env.local
:
- Wrap your app in
<ClerkProvider>
inapp/layout.tsx
:
- Require authentication to access your app by creating
middleware.ts
file at the root of your project. Themiddleware.ts
file is used to configure the Clerk middleware.
If your application has a src/
directory, you should put the middleware.ts
file inside this
src/
folder else at the root of your project.
That's it! If you visit http://localhost:3000
you will see that Clerk is protecting all the routes and you will be redirected to the sign-in page.
Configure Public Access to Specific Routes
The config
object is used to configure the middleware, you can leave this as it is. The matcher property is a regex that matches all routes except for static assets and the Next.js API routes.
You can allow other routes to be public by editing the publicRoutes
array:
Add '/'
. This is the root route of your application. It means that the homepage of your application is accessible to everyone, regardless of whether they are logged in or not.
You can use rejex to match any route you want. In my case, for Frontend Dot Dev I want everyone to have access to the courses route and sub-routes. So I added '/courses/:path*'
.
The :path*
part is a path segment wildcard, which matches any number of segments in the path.
For example, it would match/courses/css
, /courses/css/lesson/1
, etc.
Integrate the <UserButton />
Component
The <UserButton />
component to allows users to manage their account information and log out. You can add it anywhere, I'll add to the navbar of my application. When logged in, the <UserButton />
component will display the user's name and avatar.
Create Custom Sign In and Sign Up Pages
To create custom sign in page, create the following pages:
Add the following code to sign-in/[[...sign-in]]/page.tsx
.
Add the following code to sign-up/[[...sign-up]]/page.tsx
.
Update your environment variables in .env.local
:
I would recommend adding these variables directly in Vercel and then pulling them into your project using the Vercel CLI. This way they are set when you deploy your project.
Now, visit localhost:3000/sign-in
and localhost:3000/sign-up
and you will see your custom sign in and sign up pages.
Implement a Pre-Built Clerk Theme
The default theme is great but I want to update it to use the dark pre-built theme. To do that, install the @clerk/clerk-react
package, this package provides the pre-built themes.
Then, you can update the app/layout.tsx
file to use the dark theme by importing it from @clerk/themes
and passing it to the baseTheme
property of the appearance
prop.
Customize component appearance by passing variables to the appearance prop of <ClerkProvider>
.
I'll pass in the colorPrimary
and colorBackground
to match my application's color scheme. But you can also pass other properties, see the Clerk docs for more information.
Conditionally Render SignedIn
and SignedOut
Components
Import the following components to components/nav.tsx
:
SignUpButton
is a component that, when clicked, redirects to user the sign-up page.SignInButton
is a component that, when clicked, redirects the user to sign-in page.SignedIn
is a wrapper component that only renders its children if the user is signed in.SignedOut
is a wrapper component that only renders its children if the user is not signed in.UserButton
is a component that displays the current user's information and provides options to sign out or manage the account.
Now, you can update the components/nav.tsx
file to conditionally render the UserButton
, SignInButton
, and SignUpButton
components.
This is exactly what we want for a full authentication experience. If a user is signed in, they will see the UserButton
. If they are not signed in, they will see the SignInButton
and SignUpButton
.
You can also use the SignedIn
and SignedOut
components to conditionally display content based on the user's authentication status.
So, if a user is signed in, they will see the video. If they are not signed in, they will see the message prompting them to create an account.
That's it! This should give you a good idea of how to integrate Clerk into your Next.js App Router project.
Conclusion
Clerk is the best third party auth solution I have ever seen. Saving me months of work and allowing me to focus on building the core features of my application. I hope this article has helped you understand how to integrate Clerk into your Next.js App Router project. If you have any questions, please feel free to reach out to me on Twitter.