惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Forbes - Security
Forbes - Security
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
W
WeLiveSecurity
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
N
News and Events Feed by Topic
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
Engineering at Meta
Engineering at Meta
PCI Perspectives
PCI Perspectives
Martin Fowler
Martin Fowler
T
The Exploit Database - CXSecurity.com
F
Full Disclosure
WordPress大学
WordPress大学
S
Security Affairs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
SegmentFault 最新的问题
P
Privacy International News Feed
IT之家
IT之家
M
MIT News - Artificial intelligence
G
GRAHAM CLULEY
Hacker News: Ask HN
Hacker News: Ask HN
D
DataBreaches.Net
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Check Point Blog
美团技术团队
Security Latest
Security Latest
Cyberwarzone
Cyberwarzone
N
News and Events Feed by Topic
MyScale Blog
MyScale Blog
H
Help Net Security
宝玉的分享
宝玉的分享
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
The Cloudflare Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
爱范儿
爱范儿
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
AI
AI
I
InfoQ
N
News | PayPal Newsroom
TaoSecurity Blog
TaoSecurity Blog

Clerk Blog

Going to production with Clerk Deploy Clerk Init: The fastest way to start a new project Introducing Clerk CLI Middleware-based route protection bypass Postmortem: Clerk System Outage (March 10, 2026) Clerk for the AI era Add API Key support to your SaaS in minutes Postmortem: Clerk System Outage (February 19, 2026) Using Clerk in a React Native app Postmortem: DNS Provider Outage (February 10, 2026) How do I implement passkeys in Next.js? Clerk ranked #4 fastest-growing software vendor on Ramp’s December 2025 list How do I handle JWT verification in Next.js? Committing to Agent Identity: Clerk raises $50m Series C from Menlo and Anthropic’s Anthology Fund What is the best way to handle authentication in Next.js App Router? Postmortem: Database Incident (September 14–18, 2025) How do I add authentication to a Next.js app? Introducing Free Trials in Clerk Billing Postmortem: August 28, 2025 - elevated API latency and errors Introducing Mosaic: Bring Your Brand to Every Authentication Flow Multi-tenant authentication: What you need to know (and how Clerk helps) What are the risks and challenges of multi-tenancy? Resilience in Practice: Regional Failover at Clerk Build a Cross-Platform B2B App with Clerk, Expo, and Supabase Highlights from the MiduDev/Clerk Hackathon Add multi-tenancy to an app built with Clerk, Lovable, and Supabase How to build an AI coding rules app with Clerk, Lovable, and Supabase How to Build Multi-Tenant Authentication with Clerk Choosing the right SaaS architecture: Multi-Tenant vs. Single-Tenant Postmortem: June 26, 2025 service outage How to Design a Multi-Tenant SaaS Architecture What is multi-tenancy and why it matters for B2B SaaS How OAuth Works Synchronize user data from Clerk to Supabase Add subscriptions to your SaaS with Clerk Billing Getting started with Clerk Billing Multi-tenant analytics with Tinybird and Clerk How Huntr Migrated 250K Users to Clerk: A Scalable Auth Solution for Startups How to take Clerk to Production How to take your Clerk application to production A practical guide to testing Clerk Next.js applications Implementing multi-tenancy into a Supabase app with Clerk How Clerk integrates with a Next.js application using Supabase How Clerk integrates with Supabase Build a blog with tRPC, Prisma, Next.js and Clerk How to enrich PostHog events with Clerk user data How to build a secure project management platform with Next.js, Clerk, and Neon Validate your SaaS idea while building an audience Postmortem: February 6, 2025 service outage Implement Role-Based Access Control in Next.js 15 Build a Next.js sign-up form with React Hook Form Build a Next.js login page template How to implement Google authentication in Next.js 15 What is middleware in Next.js? How to customize Next.js metadata How to set environment variables in Node.js Building a React Login Page Template How to implement per-user OAuth scopes with Clerk Using Clerk SSO to access Google Calendar and other service data Streamline enterprise customer onboarding with SAML and Clerk Clerk launches EASIE SSO and eliminates SSO fees How to secure Liveblocks Rooms with Clerk in Next.js Securing Node.js Express APIs with Clerk and React Combining the benefits of session tokens and JWTs Build a task manager with Next.js, Supabase, and Clerk Comparing Clerk Webhooks vs Backend API Automate Neon schema changes with Drizzle and GitHub Actions A guide to reading authenticated user data from Clerk Role based access control with Clerk Organizations Mitigating OAuth’s recently discovered Open Response Type vulnerability Per-user B2B monetization with Stripe and Clerk Organizations Build a team-based task manager with Next.js, Neon, and Clerk Building a Hybrid Sign-Up/Subscribe Form with Stripe Elements Welcoming Colin from Zod as our inaugural Open Source Fellow Build a modern authenticated chat application with Next.js, Ably, and Clerk Build a waitlist with Clerk user metadata How to use Clerk with PostHog Identify in Next.js How to secure API Gateway using JWT and Lambda Authorizers with Clerk What are passkeys and how do they work? Comparing Authentication in React.js vs. Next.js How to Add an Onboarding Flow for your Application with Clerk Create Your Own Custom User Menu with Radix - Part 2 Introducing Webhook Workflows with Inngest & Svix Clerk raises $30M Series B from CRV and Stripe Clerk in 2023: A Year in Review Build a Movie Emoji Quiz App with Remix, Fauna, and Clerk Ultimate Guide to Magic Link Authentication Create Your Own Custom User Menu with Radix Introducing has(), protect(), and <Protect> Updated Pricing: 10,000 MAUs Free, and a new “Pro Plan” Next.js Authentication with Clerk: Streamlined SSR Handling Clerk Webhooks: Data Sync with Convex Exploring Clerk Metadata with Stripe Webhooks Empower Your Support Team With User Impersonation Clerk Webhooks: Getting Started A Complete Guide to Session Management in Next.js The Advanced Guide to Passwordless Authentication in Next.js How We Roll – Chapter 10: Roundup How We Roll – Chapter 9: Infrastructure Password-Based Authentication in Next.js
The Ultimate Guide to Next.js Authentication
Nick Parsons · 2023-11-03 · via Clerk Blog

Next.js has become the go-to framework for JavaScript and React development. It has become so popular because of the superior developer experience, performance optimization features, and its ability to facilitate different rendering options and serverless functions with ease. The combination of these attributes makes it an appealing choice for both new and experienced developers.

In Next.js 13, the Next.js team significantly upgraded the capabilities of the framework. Moving to what they call the “App Router,” Next.js is now based on React Server Components which boast performance upgrades over the previous client-server architecture.

But this shift has also led to a change in how authentication works in Next.js. In this article we want to provide an up-to-date guide on how authentication now works on Next.js so you can easily understand the concepts involved and easily add secure authentication to your Next.js applications.

The Next.js App Router

The App Router paradigm was introduced in Next.js 13 and is a significant shift in how the Next.js framework works.

Next.js was initially built as a React framework to facilitate server-side rendered and statically generated sites. But as the framework grew, more options became available:

  1. Client-Side Rendering (CSR) is where content is rendered on the client side, after the initial page load. This is ideal for pages that don’t require SEO or initial content served by the server. Common for user dashboards or pages behind authentication. You use React state and effects (useState, useEffect, etc.) as you would in a regular React app.
  2. Static Site Generation (SSG) is where pages are pre-rendered at build time and served statically. Each request receives the same HTML. This is good for content that doesn’t change often and doesn’t need to be updated with every request, such as blogs, marketing pages, and documentation, etc. Here, you use getStaticProps to fetch the required data at build time.
  3. Incremental Static Regeneration (ISR) lets you statically generate pages with the option to update them in the background. Once updated, subsequent requests get the new version. This is useful for content that updates periodically but doesn’t need real-time updates. Like with SSG, you can use getStaticProps, but this time you add a revalidate property. The revalidate interval (in seconds) determines how often the page should be updated.
  4. Server-Side Rendering (SSR) means each request is rendered on-the-fly on the server, providing fresh data. It is ideal for pages that need real-time data or when content changes frequently. Also beneficial for SEO. You use getServerSideProps to fetch data on each request.

You could have some pages work with CSR, some SSG, and some SSR. But this also led to confusion and performance issues with sites not optimally built.

Next.js 13 and the App Router are designed to simplify the developer experience within Next.js, and rebuild the framework around React Server Components. With RSC, the default for the entire site is server-side rendering, with each page being opted-in to CSR as needed. This leads to performance gains, as rendering on the server is faster, and you don’t have to send heavy JavaScript payloads over the network for hydration. It also means more sites can work on the ‘edge’ network, where sites are served from multiple servers close to users.

But this does mean that the way developers have been using Next.js thus far has now changed. The old, Pages Router continues to work, and can be used side-by-side with the App Router, but significant changes in how data is served, such as no request/response objects being passed means developers will need to rethink how they work, and how their authentication works.

Here, we’re going to go through:

  1. How authentication works with the pages router in Next.js
  2. How authentication works with the App Router in Next.js

This will give you the ability to use either as you need, and to see the differences in each paradigm when it comes to authentication.

Authentication With the Next.js Pages Router

Before we get into authentication with the App Router, let’s look at how authentication works with the Pages Router in Next.js.

Let’s create a Next.js project. To do this, we use:

You will be prompted to choose different options, but given that we are explicitly using the Pages Router, you’ll want to select “no” when asked if you would like to use the App Router.

With that done, we can install Clerk:

Next, we want to add our API keys as environmental variables in an .env.local file. To get these, sign up for a free Clerk account:

Before we go any further, we’ll also make some small changes to our homepage, at pages/index.js:

If we now run npm run dev, we’ll get this homepage:

Nextjs Authentication tutorial illustration

We’re now ready to start adding Clerk to our code. The first thing we need to do is mount the ClerkProvider. The ClerkProvider is the core component of Clerk. It is what handles all the active session data and the user context. Whenever a Clerk hook (or any other components) needs authentication data, it is getting it from the ClerkProvider.

The ClerkProvider needs needs to access headers to authenticate any user. This is important because:

To protect your entire application, it is recommended to wrap our main Component in the _app.tsx|jsx file:

This will protect every page within the application and will make the user context accessible anywhere within the app, but will also opt every page into dynamic rendering.

If you have statically served pages or are using incremental static regeneration, you can wrap route groups further into your application. For example, you might want to leave your marketing site unprotected, but wrap your dashboard components in the ClerkProvider.

Clerk requires middleware to determine the routes that need to be protected. This is in middleware.js in our root directory. This matcher will put every page and API route on the site behind authentication:

The entire application is now protected. Accessing any page while signed out will redirect you to the sign up page. If we go to the homepage again, we get redirected:

Nextjs Authentication tutorial illustration

Usually, this isn’t what you want. Your homepage, product, and marketing pages aren’t very helpful if they are behind authentication!

If you navigate to the homepage now you’ll also get this warning:

To prevent this behavior, choose one of:

  1. To make the route accessible to both signed in and signed out users, pass publicRoutes: ["/"] to authMiddleware
  2. To prevent Clerk authentication from running at all, pass ignoredRoutes: ["/((?!api|trpc))(_next.*|.+\\.[\\w]+$)", "/"] to authMiddleware
  3. Pass a custom afterAuth to authMiddleware, and replace Clerk’s default behavior of redirecting unless a route is included in public routes

So let’s make a change to add a public route:

Now, when we head to the homepage, it is available again:

Nextjs Authentication tutorial illustration

Great. But now there is no way for us to sign up or sign in. Clerk’s Next.js Authentication SDK provides helpers for determining whether a user is signed in or note, and conditionally changing the text. Let’s wrap our text in these components:

Here, if a user is signed out, they’ll see a link to a sign up page. This page doesn’t exist yet, so lets create it. It will live at pages/sign-up/[[...index]].jsx:

Not much to it. If you try to go that page, you’ll be redirected to sign in/sign up, so it will look like its working. But you are actually being redirected because that page hasn’t been defined as a public route in the middleware, so it itself is behind authentication. To get around this, we’re actually going to add it to our environment variables as a special page:

Now, if we go to that sign up page, we’ll get the modal where we can sign up:

Nextjs Authentication tutorial illustration

Then, as our environment variables say, we’re redirected to the home page:

Nextjs Authentication tutorial illustration

As you can see, the link to sign in as gone, as it was wrapped in the component that only shows it if you are signed out.

We now have a problem. We are now signed in (great!), but we can’t sign out (uh oh!). We could create a specific link for this as well, but Clerk provides a UserButton component that allows us to do this easily. Let’s add that to the homepage:

We’ve wrapped this UserButton within the SignedIn component so it’ll only show when the user is signed in:

Nextjs Authentication tutorial illustration

Using that button, the user can easily adjust their profile as well as sign out of the application.

Now the user is signed in, they can visit other pages. Let’s create a pages/protected.jsx page:

The code uses the clerkClient, getAuth, and buildClerkProps utilities from the @clerk/nextjs library to handle user authentication. If a user is not authenticated (determined by the absence of a user prop), the page prompts the user to log in. If authenticated, the page displays a personalized welcome message.

The server-side function getServerSideProps checks for the userId in the incoming request using the getAuth function; if the userId is present (indicating authentication), it fetches detailed user information from Clerk via clerkClient.users.getUser. The fetched data is then streamlined to a simpler format, extracting only necessary fields like the user’s first name and last name.

The getServerSideProps function concludes by returning the user data, if any, along with additional props sourced from buildClerkProps, ensuring the frontend receives the necessary data to render the page appropriately.

This renders as:

Nextjs Authentication tutorial illustration

Here, the authentication is checked on the server before the page is rendered via getServerSideProps. We can also check whether the user is authenticated on the client. Let’s create a pages/protected-client.jsx page:

Which renders this page:

Nextjs Authentication tutorial illustration

One final part of Next.js we can protect with authentication–API routes. With the pages router, any route within pages/api is returned as an API. Let’s protect an API route at pages/api/auth.js:

This uses the getAuth helper that retrieves the authentication state to protect the API route. If we call this within the browser, we’ll get the user JSON:

Nextjs Authentication tutorial illustration

You now have a protected Next.js application using the pages router. Let’s move on to the App Router.

Authentication with the Next.js App Router

We’re now going to work through an entire example with the Next.js App Router. Some of this is the same as above, particularly, the set up, but once we get into the actual authentication, there are going to be some differences.

Let’s create a new Next.js project:

This time, when you are prompted to use the App Router, select “yes”.

Then install Clerk into this project:

And then add our API keys in an .env.local file:

We’ll spool up another bare-bones homepage, this time at app/page.js:

If we now run npm run dev, we’ll get this homepage:

Nextjs Authentication tutorial illustration

Looks like we have some nicer default styling with the App Router.

Next up is to add the ClerkProvider. This is the first point at which there is a difference between the pages router and the App Router. With the App Router, we’re going to add the ClerkProvider to our layout.js:

The App Router doesn’t use the _app.js file. Instead, layout.js lets you set a global layout for your application. Therefore you can add the ClerkProvider to e.g. the dashboard/layout.js file, and only the files within that route group would require a login. To repeat from above, this is important because the ClerkProvider requires dynamic rendering. If you nest the ClerkProvider at a lower level, this allows you to serve the landing and marketing pages statically.

Next step is the middleware. Again, this is in middleware.js in our root directory. This time, we’ll start with our homepage as a public route:

Clerk is now protecting the entire application. Let’s change our homepage to use the SignedOut component so we can sign in to the app:

The link now shows on the page:

Nextjs Authentication tutorial illustration

Next we’ll add the two other components that will be important for signing up/in/out. First, the sign up page, which will be at app/sign-up/[[...sign-up]]/page.jsx:

Remember to also add these new endpoints to your .env.local:

Second, we need the user button:

Now, when we click the sign up/in link we again go through to the Clerk modal:

Nextjs Authentication tutorial illustration

Once we sign in we are redirected back to the homepage, now with the user button:

Nextjs Authentication tutorial illustration

With the user signed in, let’s do the same as with the pages router: create a protected page and a protected API.

Again, for protected pages, we can check for authentication on the server or on the client. Let’s quickly do the client side as that is similar to the pages router:

The only difference between the App Router and the pages router version here is the “use client” directive. By default, all components in the App Router are server components, so will render on the server. The “use client” directive opts this component into client-side rendering, so we can then use Clerk hooks.

This renders as:

Nextjs Authentication tutorial illustration

For server rendering, Clerk has two App Router-specific helpers that you can use with your Server Components:

  1. auth() will return the Authentication object of the currently active user. One of the fundamental differences with the App Router is that you don’t have to inspect the request object constantly for authentication headers. Instead they are available in the global scope through Next.js’s headers() and cookies() functions, that ClerkProvider gives you access to.
  2. currentUser() will return the User object of the currently active user so you can render information, like their first and last name, directly from the server.

Here, we’re going to use both to get information about the user on a protected page:

Which gives us a page with user information rendered:

Nextjs Authentication tutorial illustration

For API routes, the routing is different, but the code is similar. Let’s build an API route under app/api/user/route.jsx:

We don’t have the request and response objects with the App Router, so get all our authentication data from our Clerk helpers (which get it from the ClerkProvider which gets it from the global scope via the Next.js headers() function). We can return a JSON of the user’s information:

Nextjs Authentication tutorial illustration

And that’s it. You have server-side, client-side, and API route authentication using the Next.js App Router.

Authenticating with the App Router

The Next.js App Router offers significant performance gains compared to the traditional pages router. However, you can absolutely continue leveraging the pages router in your Next.js applications – Clerk supports authentication with both routing approaches.

To learn more about the App Router, check out the official Next.js documentation. If you would like to get started with Clerk, sign up for a free account and follow along with our Next.js Quickstart.