Skip to main content
Docs

Next.js Quickstart (App Router)

Use this pre-built prompt to get started faster.

Create a new Next.js app

If you don't already have a Next.js app, run the following commands to create a new one.

terminal
npm create next-app@latest clerk-nextjs -- --yes
cd clerk-nextjs
npm install
terminal
pnpm create next-app clerk-nextjs --yes
cd clerk-nextjs
pnpm install
terminal
yarn create next-app clerk-nextjs --yes
cd clerk-nextjs
yarn install
terminal
bunx create-next-app clerk-nextjs --yes
cd clerk-nextjs
bun install

Install @clerk/nextjs

The Clerk Next.js SDK gives you access to prebuilt components, hooks, and helpers to make user authentication easier.

Run the following command to install the SDK:

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

Add clerkMiddleware() to your app

clerkMiddleware() grants you access to user authentication state throughout your app. It also allows you to protect specific routes from unauthenticated users. To add clerkMiddleware() to your app, follow these steps:

Important

If you're using Next.js ≤15, name your file middleware.ts instead of proxy.ts. The code itself remains the same; only the filename changes.

  1. Create a proxy.ts file.

    • If you're using the /src directory, create proxy.ts in the /src directory.
    • If you're not using the /src directory, create proxy.ts in the root directory.
  2. In your proxy.ts file, export the clerkMiddleware() helper:

    proxy.ts
    import { clerkMiddleware } from '@clerk/nextjs/server'
    
    export default clerkMiddleware()
    
    export const config = {
      matcher: [
        // Skip Next.js internals and all static files, unless found in search params
        '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
        // Always run for API routes
        '/(api|trpc)(.*)',
      ],
    }
  3. By default, clerkMiddleware() will not protect any routes. All routes are public and you must opt-in to protection for routes. See the clerkMiddleware() reference to learn how to require authentication for specific routes.

Add <ClerkProvider> to your app

The <ClerkProvider> component provides session and user context to Clerk's hooks and components. It's recommended to wrap your entire app at the entry point with <ClerkProvider> to make authentication globally accessible. See the reference docs for other configuration options.

Add the <ClerkProvider> component to your app's layout, as shown in the following example:

app/layout.tsx
import type { Metadata } from 'next'
import { ClerkProvider } from '@clerk/nextjs'
import { Geist, Geist_Mono } from 'next/font/google'
import './globals.css'

14 lines collapsedconst geistSans = Geist({ variable: '--font-geist-sans', subsets: ['latin'], }) const geistMono = Geist_Mono({ variable: '--font-geist-mono', subsets: ['latin'], }) export const metadata: Metadata = { title: 'Clerk Next.js Quickstart', description: 'Generated by create next app', }
export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { return ( <ClerkProvider> <html lang="en"> <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}> {children} </body> </html> </ClerkProvider> ) }

Create a header with Clerk components

You can control which content signed-in and signed-out users can see with the prebuilt control components. The following example creates a header using the following components:

app/layout.tsx
import type { Metadata } from 'next'
import {
  ClerkProvider,
  SignInButton,
  SignUpButton,
  SignedIn,
  SignedOut,
  UserButton,
} from '@clerk/nextjs'
import { Geist, Geist_Mono } from 'next/font/google'
import './globals.css'

20 lines collapsedconst geistSans = Geist({ variable: '--font-geist-sans', subsets: ['latin'], }) const geistMono = Geist_Mono({ variable: '--font-geist-mono', subsets: ['latin'], }) export const metadata: Metadata = { title: 'Clerk Next.js Quickstart', description: 'Generated by create next app', } export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) {
return ( <ClerkProvider> <html lang="en"> <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}> <header className="flex justify-end items-center p-4 gap-4 h-16"> {/* Show the sign-in and sign-up buttons when the user is signed out */} <SignedOut> <SignInButton /> <SignUpButton> <button className="bg-[#6c47ff] text-white rounded-full font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 cursor-pointer"> Sign Up </button> </SignUpButton> </SignedOut> {/* Show the user button when the user is signed in */} <SignedIn> <UserButton /> </SignedIn> </header> {children} </body> </html> </ClerkProvider> ) }

Run your project

Run your project with the following command:

terminal
npm run dev
terminal
pnpm run dev
terminal
yarn dev
terminal
bun run dev

Create your first user

  1. Visit your app's homepage at http://localhost:3000.

  2. Select "Sign up" on the page and authenticate to create your first user.

  3. To make configuration changes to your Clerk development instance, claim the Clerk keys that were generated for you by selecting Claim your application in the bottom right of your app. This will associate the application with your Clerk account.

Next steps

Learn more about Clerk authentication flows, route protection, user data access, and deploying your app using the following guides.

Create a custom sign-in or sign-up page

This tutorial gets you started with Clerk's <SignInButton /> component, which uses the Account Portal. If you don't want to use the Account Portal, read this guide about creating a custom authentication page.

Add custom onboarding to your authentication flow

If you need to collect additional information about users that Clerk's Account Portal or prebuilt components don't collect, read this guide about adding a custom onboarding flow to your authentication flow.

Protect specific routes

This tutorial taught you that by default, clerkMiddleware() will not protect any routes. Read this reference doc to learn how to protect specific routes from unauthenticated users.

Protect content and read user data

Learn how to use Clerk's hooks and helpers to access the session and user data in your Next.js app.

Next.js SDK Reference

Learn more about the Clerk Next.js SDK and how to use it.

Deploy to Production

Learn how to deploy your Clerk app to production.

Feedback

What did you think of this content?

Last updated on

GitHubEdit on GitHub