Skip to Content
Clerk logo

Clerk Docs

Ctrl + K
Go to

Use Clerk with Next.js

Learn how to use Clerk to quickly and easily add secure authentication and user management to your Next.js application. Clerk works seamlessly in both client side and server side components.

Install @clerk/nextjs

Once you have a Next.js application ready, you need to install Clerk's Next.js SDK. This gives you access to prebuilt components and hooks, as well as helpers for Next.js API routes, server-side rendering, and middleware.

npm install @clerk/nextjs
yarn add @clerk/nextjs
pnpm add @clerk/nextjs

Set environment keys

Below is an example of an .env.local file. If you are signed into your Clerk Dashboard, your keys should become visible by clicking on the eye icon.


Mount <ClerkProvider />

Add the <ClerkProvider /> wrapper to your application. The <ClerkProvider /> component wraps your Next.js application to provide active session and user context to Clerk's hooks and other components. A reasonable default approach is to have <ClerkProvider /> wrap the <body/> to enable the context to be accessible anywhere within the app.

The <ClerkProvider /> component needs to access headers to authenticate correctly. This means anything wrapped by the provider will be opted into dynamic rendering at request time. If you have static-optimized or ISR pages that you would prefer not to be opted into dynamic rendering, make sure they are not wrapped by <ClerkProvider />.

This is easiest to accomplish by ensuring that <ClerkProvider /> is added further down the tree to wrap route groups that explicitly need authentication instead of having the provider wrap your application root as recommended above. For example, if your project includes a set of landing/marketing pages as well as a dashboard that requires login, you would create separate (marketing) and (dashboard) route groups. Adding <ClerkProvider /> to the (dashboard)/layout.jsx layout file will ensure that only those routes are opted into dynamic rendering, allowing the marketing routes to be statically optimized.

import { ClerkProvider } from '@clerk/nextjs' export const metadata = { title: 'Next.js 13 with Clerk', } export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <ClerkProvider> <html lang="en"> <body>{children}</body> </html> </ClerkProvider> ) }
import { ClerkProvider } from "@clerk/nextjs"; import type { AppProps } from "next/app"; function MyApp({ Component, pageProps }: AppProps) { return ( <ClerkProvider {...pageProps}> <Component {...pageProps} /> </ClerkProvider> ); } export default MyApp;

The root layout is a server component. If you plan to use the <ClerkProvider /> outside the root layout, it will need to be a server component as well.

Protect your application

Now that Clerk is installed and mounted in your application, it’s time to decide which pages are public and which need to hide behind authentication. We do this by creating a middleware.ts file at the root folder (or inside src/ if that is how you set up your app).

import { authMiddleware } from "@clerk/nextjs"; // This example protects all routes including api/trpc routes // Please edit this to allow other routes to be public as needed. // See for more information about configuring your middleware export default authMiddleware({}); export const config = { matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'], };

With this middleware, your entire application is protected. If you try to access it, the middleware will redirect you to your Sign Up page. If you want to make other routes public, check out the authMiddleware reference page.

At this point, your application is fully protected by Clerk and uses Clerk's Account Portal pages that are available out of box. Start your Next.js application via npm run dev, visit http://localhost:3000, and sign up to get access to your application.

Build your own sign in and sign up pages

In addition to the Account Portal, Clerk also offers a set of prebuilt components that you can use instead to embed sign in, sign up, and other user management functions into your Next.js application. We are going to use the <SignIn /> and <SignUp /> components by utilizing the Next.js optional catch-all route.

Build your sign up page

import { SignUp } from "@clerk/nextjs"; export default function Page() { return <SignUp />; }
import { SignUp } from "@clerk/nextjs"; export default function Page() { return <SignUp />; }

Build your sign in page

import { SignIn } from "@clerk/nextjs"; export default function Page() { return <SignIn />; }
import { SignIn } from "@clerk/nextjs"; export default function Page() { return <SignIn />; }

By default, the Clerk components inherit the font family. create-next-app does not apply a global font family. When you launch your application, you may notice that the font family is different.

Update your environment variables

Next, add environment variables for the signIn, signUp, afterSignUp, and afterSignIn paths:


These values control the behavior of the components when you sign in or sign up and when you click on the respective links at the bottom of each component.

Embed the <UserButton />

The <UserButton /> allows users to manage their account information and log out, thus allowing you to complete a full authentication circle.

You can add it anywhere you want, but next to the logo in your main application page is a good start.

import { UserButton } from "@clerk/nextjs"; export default function Home() { return ( <div> <UserButton afterSignOutUrl="/"/> </div> ) }
import { UserButton } from "@clerk/nextjs"; export default function Example() { return ( <> <header> <UserButton afterSignOutUrl="/"/> </header> <div>Your page's content can go here.</div> </> ); }

Sign up for your application

Now start your Next.js application via npm run dev, visit http://localhost:3000, and sign up to get access to your application.

Read session and user data

Clerk provides a set of hooks and helpers that you can use to access the active session and user data in your Next.js application. Here are examples of how to use these helpers in both the client and server side to get you started.

Client side


The useAuth hook is a convenient way to access the current auth state. This hook provides the minimal information needed for data-loading and helper methods to manage the current active session.

"use client"; import { useAuth } from "@clerk/nextjs"; export default function Example() { const { isLoaded, userId, sessionId, getToken } = useAuth(); // In case the user signs out while on the page. if (!isLoaded || !userId) { return null; } return ( <div> Hello, {userId} your current active session is {sessionId} </div> ); }


The useUser hook is a convenient way to access the current user data where you need it. This hook provides the user data and helper methods to manage the current active session.

"use client"; import { useUser } from "@clerk/nextjs"; export default function Example() { const { isLoaded, isSignedIn, user } = useUser(); if (!isLoaded || !isSignedIn) { return null; } return <div>Hello, {user.firstName} welcome to Clerk</div>; }

Server side

API Routes

You can protect your API routes by using the getAuth helper and retrieve data from your own systems.

import type { NextApiRequest, NextApiResponse } from "next"; import { getAuth } from "@clerk/nextjs/server"; export default function handler(req: NextApiRequest, res: NextApiResponse) { const { userId } = getAuth(req); if (!userId) { res.status(401).json({ error: "Unauthorized" }); return; } // retrieve data from your database res.status(200).json({}); }

In some cases, you may need the full User object. For example, if you want to access the user's email address or name. You can use the clerkClient helper to get the full User object.

import { clerkClient } from "@clerk/nextjs"; import { getAuth } from "@clerk/nextjs/server"; import type { NextApiRequest, NextApiResponse } from "next"; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { const { userId } = getAuth(req); if (!userId) { return res.status(401).json({ error: "Unauthorized" }); } const user = userId ? await clerkClient.users.getUser(userId) : null; // use the user object to decide what data to return return res.status(200).json({}); }

Server side render user data


currentUser() loads the User object for the authenticated user from Clerk's backend API. This is helpful if you want to render information, like their first and last name, directly from the server.

Under the hood, this calls fetch() so it is automatically deduped per request.

import { currentUser } from "@clerk/nextjs"; import type { User } from "@clerk/nextjs/api"; export default async function Page() { const user: User | null = await currentUser(); // ... }


Clerk has introduced a new auth() helper that returns the same Authentication Object as getAuth(req) in middleware, getServerSideProps, and API routes.

Since request data like headers() and cookies() is now available in the global scope for Next.js, you no longer need to explicitly pass a Request object to Clerk.

import { auth } from "@clerk/nextjs"; export default function Page() { const { userId } = auth(); // ... }

Next steps

Now that your Next.js application is integrated with Clerk, you will want to read the following documentation:

Customization & Localization

Learn how to customize and localize the Clerk components.

Learn More

Authentication Components

Learn more about all our authentication components.

Learn More

Client Side Helpers

Learn more about our client side helpers and how to use them.

Learn More

Next.js SDK Reference

Learn more about additional Next.js methods.

Learn More

What did you think of this content?

Clerk © 2023