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.
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).
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.
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
import { SignUp } from "@clerk/nextjs";
const SignUpPage = () => (
<SignUp path="/sign-up" routing="path" signInUrl="/sign-in" />
);
export default SignUpPage;
Build Your Sign In
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](/_next/image?url=%2Fimages%2Fcommon%2Fpath-setting.png&w=3840&q=75)
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.
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.
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.
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.
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 { 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>
).
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.
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: