Next.js Authentication
Easily add secure, beautiful, and fast authentication to Next.js with Clerk.
Learn more about Next.js authentication with Clerk.
Overview
Clerk is the easiest way to add secure, beautiful, and fast authentication to your Next.js application. Clerk provides an NPM library tailored specifically to Next.js authentication, with helpers for React pages, API routes, server-side rendering, and edge middleware.This guide shows how to install and use Clerk to solve the most common Next.js authentication challenges.
πΒ Live demo
π©βπ» Looking for a quickstart? Check out the Clerk + Nextjs starter repo
Installation
Before you start
You need to create a Clerk Application in your Clerk Dashboard. For more information, check out our Set up your application guide.
Create a Next.js application
Start by creating a new Next.js application with the npx
CLI:
npx create-next-app@latest
If you wish to use TypeScript, just add --typescript
to the command above. Clerk is written in TypeScript, so it works out of the box without any extra configuration.
Need more help? The Next.js documentation goes into more detail about creating applications.
Install Clerk's SDK
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.
1# Navigate to your application's root directory2cd yourapp34# Install the clerk/nextjs package5npm install @clerk/nextjs
Now, we need to set three environment variables for Clerk's SDK. Go to the API Keys page and start by copying the Frontend API key. Then, add it a .env.local file in your application root, with the name NEXT_PUBLIC_CLERK_FRONTEND_API
:
1# Replace [frontend-api-key] with your actual Frontend API key2echo "NEXT_PUBLIC_CLERK_FRONTEND_API=[frontend-api-key]" >> .env.local
Next, go back to the API Keys page and copy the Backend API key. Then, add it in the same .env.local file, with the name CLERK_API_KEY
:
1# Replace [backend-api-key] with your actual Backend API key2echo "CLERK_API_KEY=[backend-api-key]" >> .env.local
Finally, go back to the API Keys page and copy the JWT verification key. Again, add it in the sameΒ .env.local file, with the name CLERK_JWT_KEY
:
1# Replace [jwt-verification-key] with your actual JWT Verification key2echo "CLERK_JWT_KEY=[jwt-verification-key]" >> .env.local
Install <ClerkProvider />
Clerk requires your React application to be wrapped in the <ClerkProvider/>
component. In Next.js, this is done in pages/_app.js
.
1import { ClerkProvider } from '@clerk/nextjs';23function MyApp({ Component, pageProps }) {4return (5<ClerkProvider {...pageProps} >6<Component {...pageProps} />7</ClerkProvider>8);9}1011export default MyApp;
Notice the {...pageProps}
part - that's what makes all the SSR magic possible.
That's all! π
To run your app, start the development server and navigate to https://localhost:3000
npm run dev
Clerk is installed, but you still have configure your application to use authentication. Read on to learn how to protect pages, API routes, and more.
Protecting pages
Using Control Components
After installing Clerk, the most common next step is to restrict page access to signed in users.The easiest way to accomplish this is to leverage our flexible Control Components:
- β
<SignedIn/>
: Renders its children only when a user is signed in. - β
<SignedOut/>
: Renders its children only when there's no active user. - β
<RedirectToSignIn/>
: Triggers a redirect to the sign in page.
The following example shows you how to compose our flexible Control Components to build authentication flows that match your needs. Please note that you don't need to use any additional APIs, everything shown below is just Javascript.
1import { ClerkProvider, SignedIn, SignedOut, RedirectToSignIn } from '@clerk/nextjs';2import { useRouter } from 'next/router';34// List pages you want to be publicly accessible, or leave empty if5// every page requires authentication. Use this naming strategy:6// "/" for pages/index.js7// "/foo" for pages/foo/index.js8// "/foo/bar" for pages/foo/bar.js9// "/foo/[...bar]" for pages/foo/[...bar].js10const publicPages = [];1112function MyApp({ Component, pageProps }) {13// Get the pathname14const { pathname } = useRouter();1516// Check if the current route matches a public page17const isPublicPage = publicPages.includes(pathname);1819// If the current route is listed as public, render it directly20// Otherwise, use Clerk to require authentication21return (22<ClerkProvider>23{isPublicPage ? (24<Component {...pageProps} />25) : (26<>27<SignedIn>28<Component {...pageProps} />29</SignedIn>30<SignedOut>31<RedirectToSignIn />32</SignedOut>33</>34)}35</ClerkProvider>36);37}3839export default MyApp;
Visit http://localhost:3000 to see your page. The home "/"
page is not listed in the publicPages
array, so you'll immediately get redirected to the Clerk Hosted Sign In page.
Using getServerSideProps (SSR)
You can also leverage the SSR capabilities of Clerk and NextJS to redirect unauthenticated users to a sign in page during SSR - even before the components render on the client side.
Next.js uses special export named getServerSideProps
to enable server-side rendering. The withServerSideAuth
Clerk helper provides access to the auth state.
1import { withServerSideAuth } from "@clerk/nextjs/ssr";23export const getServerSideProps = withServerSideAuth(({ req, resolvedUrl }) => {4const { sessionId } = req.auth;56if (!sessionId) {7return { redirect: { destination: "/sign-in?redirect_url=" + resolvedUrl } };8}910return { props: {} };11});
This snippets redirects unauthenticated visitors to the sign in page. Notice that we also added a redirect_url
query param - Clerk will redirect the user back to the original destination after a successful sign in flow.
Using a _middleware function (Edge)
Alternatively, if you're using Edge Functions you can restrict access to a page using the Clerk edge middleware auth helper as shown below:
1import { withEdgeMiddlewareAuth } from "@clerk/nextjs/edge-middleware";2import { NextResponse } from "next/server";34export default withEdgeMiddlewareAuth((request) => {5const { sessionId } = request.auth;67if (!sessionId) {8const destination = request.nextUrl.href;9const url = request.nextUrl.clone();10url.pathname = "/sign-in";11url.searchParams.set("redirect_url", destination);12return NextResponse.redirect(url);13}1415return NextResponse.next();16});17
This snippets redirects unauthenticated visitors to the sign in page. Notice that we also added a redirect_url
query param - Clerk will redirect the user back to the original destination after a successful sign in flow.
A great use case for the above middleware is restricting access to entire paths, eg: /protected-pages/*
. Let's say you have the following file structure, and you want to restrict access to the whole /protected-page
directory:
pages/ββ protected-pages/β ββ _middleware.tsxβ ββ user/β β ββ profile/β β β ββ password.tsxβ β ββ index.tsxindex.tsx_app.tsx
Simply create a _middleware.tsx
file under protected-pages/
and paste the middleware from the snippet.
Accessing authentication data
Clerk is the only provider that seamlessly authenticates users across all four Next.js contexts:
- Pages
- getServerProps
- API routes
- Edge middleware
Each context has access to Clerk's auth singleton, which contains the data necessary for authentication and data loading:
- userId: The ID of the active user, or
null
when signed out. In data-loaders, this is often the only piece of information needed to securely retrieve the data associated with a request. - sessionId: The ID of the active session, or
null
when signed out. This is primarily used in audit logs to enable device-level granularity instead of user-level. - getToken({ template?: string; }): Retrieves a signed JWT that is structured according to the corresponding JWT template in your dashboard. If no template parameter is provided, a default Clerk session JWT is returned.
Page authentication
In Next.js pages, the useAuth
hook retrieves the auth singleton from within your React components.
1import { useAuth } from '@clerk/nextjs';23const Page = () => {4const { isLoaded, userId, sessionId, getToken } = useAuth();56// Handle these cases in case the user signs out while on the page.7if (!isLoaded || !userId) {8return null;9}1011return <div>Hello, {userId}</div>;12};
API routes authentication
In API routes, the withAuth
helper adds the auth singleton to the request object.
1import { withAuth } from "@clerk/nextjs/api";23export default withAuth(async (req, res) => {4const { userId, sessionId, getToken } = req.auth;5const supabaseToken = await getToken({ template: 'supabase' });6// Load any data your application needs for the API route7return { data: {} };8});9
Server-side rendering (SSR) authentication
Next.js uses special export named getServerSideProps
to enable server-side rendering. The withServerSideAuth
helper adds the auth singleton to the request object.
1import { withServerSideAuth } from "@clerk/nextjs/ssr";23export const getServerSideProps = withServerSideAuth(async ({ req }) => {4const { userId, sessionId, getToken } = req.auth;5const hasuraToken = await getToken({ template: 'hasura' });6// Load any data your application needs and pass to props7return { props: {} };8});910export default MyPage(){11return ...;12}
Edge middleware authentication
In edge middleware, the withEdgeMiddlewareAuth
helper injects the auth property to the request object.
1import { withEdgeMiddlewareAuth } from "@clerk/nextjs/edge-middleware";23export default withEdgeMiddlewareAuth(async req => {4const { userId, sessionId, getToken } = req.auth;5const supabaseToken = await getToken({ template: 'supabase' });67// Run your middleware89// Complete response10return NextResponse.next();11});
Enabling full server side rendering
To make auth as fast as possible, Clerk uses short-lived stateless JWT tokens by default, requiring no network requests.
If desired, Clerkβs complete User objects can also be retrieved during SSR. Since these objects require network requests to retrieve, so you need to explicitly enable server-side user fetching by passing a flag to the data-loader:
1import { withServerSideAuth } from "@clerk/nextjs/ssr";23export const getServerSideProps = withServerSideAuth({ loadUser: true });45// or, if you also need a custom getServerSideProps handler:6export const getServerSideProps = withServerSideAuth(7({ req }) => {8const { userId } = req.auth;9// fetch data10return { props: { yourData: "here" } };11},12{ loadUser: true }13);
Next steps
You now have a working Next.js + Clerk app. Going forward, you can:
- Check out the clerk-nextjs-starter template
- Learn more about the Clerk Components and the Clerk Hosted Pages.
- Read our in-depth guides on the most common use cases in the How-to Guides section.
- When you're ready, learn how to deploy your app to production.
- Get support or at least say hi in our Discord channel π