Next.js
Next.js App Router (beta)

Use Clerk with Next.js

Learn how to use Clerk with Next.js App Router including protecting pages and accessing authentication data.

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 our prebuilt components and hooks for React, as well as our helpers for Next.js API routes, server-side rendering, and edge middleware.

npm install @clerk/nextjs

Set Environment Keys

Below is an example of your .env.local file. To get the respective keys go to the API Keys page in the Clerk dashboard.

.env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_••••••••••••••••••••••••••••••••••
CLERK_SECRET_KEY=sk_test_••••••••••••••••••••••••••••••••••

Configure <ClerkProvider>

Update your root layout to include the <ClerkProvider> wrapper. The <ClerkProvider> component wraps your Next.js application to provide active session and user context to Clerk's hooks and other components.

app/layout.tsx
import React from "react"
import { ClerkProvider } from "@clerk/nextjs/app-beta";
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
      <html lang="en">
        <head>
          <title>Next.js 13 with Clerk</title>
        </head>
        <ClerkProvider>
        <body>{children}</body>
        </ClerkProvider>
      </html>
  );
}
⚠️

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

Embedding Clerk Components

Clerk offers a set of prebuilt components that you can use to embed sign in, sign up, and other user management functions into your Next.js application.

The functionality of the components are controlled by the instance settings you specify in your Clerk Dashboard (opens in a new tab).

⚠️

The /app directory currently does not support fast "path" routing between the different pages of these components, so you should use the default "hash" routing instead.

Sign In Component

app/sign-in/page.tsx
import { SignIn } from '@clerk/nextjs/app-beta';
 
export default function Page() {
  return <SignIn signUpUrl="/sign-up"/>;
}

Sign Up Component

app/sign-up/page.tsx
import { SignUp } from '@clerk/nextjs/app-beta';
 
export default function Page() {
  return <SignUp signInUrl="/sign-in"/>;
}
ℹ️

If you want to learn more about learn more about the prebuilt components check out our Clerk Components documentation.

Add Middleware

To use server side functionality, you need to add the Clerk middleware to your Next.js application. This allows you to access the session in your Next.js API routes and server-side rendered pages. Middleware should be placed at the root of your project.

middeware.ts
import { withClerkMiddleware } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import type { NextRequest } from 'next/server'
 
export default withClerkMiddleware((req: NextRequest) => {
  return NextResponse.next();
});
 
// Stop Middleware running on static files
export const config = { matcher: '/((?!.*\\.).*)' }
 

Protecting Your Pages

Clerk offers two ways to protect your Next.js application, you can use Next.js Middleware or using our Control Components.

Using Middleware is the most comprehensive way to implement page protection in your app. Below is an example of page protection using Middleware.

middeware.ts
import { withClerkMiddleware, getAuth } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
 
// Set the paths that don't require the user to be signed in
const publicPaths = ["/", "/sign-in*", "/sign-up*"];
 
const isPublic = (path: string) => {
  return publicPaths.find((x) =>
    path.match(new RegExp(`^${x}$`.replace("*$", "($|/)")))
  );
};
 
export default withClerkMiddleware((request: NextRequest) => {
  if (isPublic(request.nextUrl.pathname)) {
    return NextResponse.next();
  }
  // if the user is not signed in redirect them to the sign in page.
  const { userId } = getAuth(request);
 
  if (!userId) {
    // redirect the users to /pages/sign-in/[[...index]].ts
 
    const signInUrl = new URL("/sign-in", request.url);
    signInUrl.searchParams.set("redirect_url", request.url);
    return NextResponse.redirect(signInUrl);
  }
  return NextResponse.next();
});
 
export const config = { matcher: "/((?!.*\\.).*)" };
 

Accessing Auth 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. We have included examples of how to use these helpers in both the client and server side to get you started.

Client Side

useAuth

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.

app/example.tsx
'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>;
};

useUser

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.

pages/example.tsx
'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>;
  };
 
export default Home

Server Side

API Routes

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

pages/api/auth.ts
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.

pages/api/auth.ts
import { getAuth, clerkClient } 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({});
}

currentUser()

Current user 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.

page.tsx
import { currentUser } from '@clerk/nextjs/app-beta';
import type { User } from '@clerk/nextjs/dist/api'
 
export default async function Page() {
  const user: User | null = await currentUser();
  // ...
}

auth()

We have 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

app/page.tsx
import { auth } from '@clerk/nextjs/app-beta';
 
export default function Page() {
  const { userId: string | null } = auth();
  // ...
}

Next Steps

Now you have an application integrated with Clerk you will want to read the following documentation: