Next.js
Next.js (stable)

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 on both client side and server side rendered pages.

ℹ️

Are you looking to use Next.js App Layout Beta? Check out our Next.js App Beta guide.

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 our helpers for Next.js API routes, server-side rendering, and middleware.

your-project
npm install @clerk/nextjs

Set Environment Keys

Below is an example of an .env.local file. To get your keys go to the API Keys page on the Clerk dashboard (opens in a new tab).

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

Mount <ClerkProvider>

Clerk requires your Next.js application to be wrapped in the <ClerkProvider/> component. The <ClerkProvider /> component wraps your Next.js application to provide active session and user context to Clerk's hooks and other components.

_app.tsx
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;

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. We are going to use the <SignIn />,<SignUp /> components by utlizing the Next.js optional catch all route (opens in a new tab).

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

Build Your Sign Up

/pages/sign-up/[[...index]].tsx
import { SignUp } from "@clerk/nextjs";
 
const SignUpPage = () => (
  <SignUp path="/sign-up" routing="path" signInUrl="/sign-in" />
);
export default SignUpPage;

Build Your Sign In

/pages/sign-in/[[...index]].tsx
import { SignIn } from "@clerk/nextjs";
 
const SignInPage = () => (
  <SignIn path="/sign-in" routing="path" signUpUrl="/sign-up" />
);
export default SignInPage;

Update your dashboard settings

To make sure you are using the embedded components you will need to update your instance settings in the Clerk Dashboard (opens in a new tab) to use the embedded components.

Path setting Imagee
ℹ️

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.

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: "/((?!_next/image|_next/static|favicon.ico).*)",
};

Protecting Your Pages

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

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

middleware.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: "/((?!_next/image|_next/static|favicon.ico).*)",
};

Read Session & 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. 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.

pages/example.tsx
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
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.

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({});
}

Server Side Rendering

You can access the active session and user data in your getServerSideProps using the getAuth helper.

ℹ️

Please note the addition of buildClerkProps in the return statement, which informs our React helpers of the authentication state during server-side rendering (like useAuth(), <SignedIn>, and <SignedOut>).

pages/example.tsx
import { getAuth, buildClerkProps } from "@clerk/nextjs/server";
import { GetServerSideProps } from "next";
 
export const getServerSideProps: GetServerSideProps = async (ctx) => {
  const { userId } = getAuth(ctx.req);
 
  if (!userId) {
    // handle user is not logged in.
  }
 
  // Load any data your application needs for the page using the userId
  return { props: { ...buildClerkProps(ctx.req) } };
};

You can also access the full user object before passing it to the page using the clerkClient helper.

pages/example.tsx
import { clerkClient, getAuth, buildClerkProps } from "@clerk/nextjs/server";
import { GetServerSideProps } from "next";
 
export const getServerSideProps: GetServerSideProps = async (ctx) => {
  const { userId } = getAuth(ctx.req);
 
  const user = userId ? await clerkClient.users.getUser(userId) : undefined;
 
  return { props: { ...buildClerkProps(ctx.req, { user }) } };
};

Next Steps

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