Cookie-based sessions for Next.js
The session lives in a signed and encrypted cookie, so there is no session store to run and no lookup on the way in. Reading it is a decrypt, which is why these pages render on the server with no loading state.
Every example logs in with a fake user. Logging in sleeps 250ms to stand in for a database call; reading the session does not, because it never touches one.
Start here
App Router, the shape the Next.js authentication guide describes.
The default. A form posts to a Server Action, the action writes the session, the page reads it on the server.
- Server Actions
- Data Access Layer
- Protected route
When cacheComponents is on. The session is a dynamic hole inside a prerendered page, and never inside use cache.
- use cache
- Suspense
- useActionState
- Protected route
Reading the session from the client
When the session UI lives in a Client Component instead of on the server.
When a Client Component owns the session UI and reads it over fetch, with optimistic updates.
- Route Handlers
- SWR
- Proxy
When login should answer with a redirect instead of JSON, and the page re-renders on the server.
- Route Handlers
- redirect
Other patterns
Sign in through a provider. iron-session seals the state on the way out and holds the session on the way back.
- sealData
- state
- Route Handlers
Passwordless login: seal a token into a URL, unseal it on the way back, then start the session.
- sealData
- unsealData
- useActionState
Pages Router
Same library, older router. New apps should use the App Router examples above.
The Pages Router equivalent of the SWR example above.
- API Routes
- getServerSideProps
- SWR
The Pages Router equivalent of the redirect example above.
- API Routes
- redirect
How this maps to the Next.js docs
- Sessions are stateless. The Next.js guide splits sessions into stateless and database-backed. iron-session is the stateless one: the data is sealed into the cookie, so there is nothing to look up and nothing to run.
- Check the session next to the data it protects. Read it in the Server Component, Server Action or Route Handler that needs it. A layout does not protect the pages under it, and neither does a redirect in
proxy.ts. proxy.tsis an optimistic check. Middleware was renamed Proxy in Next.js 16. Redirecting from there is a convenience: it is one matcher change away from not running, and CVE-2025-29927 was a Next.js bug that let requests skip it. iron-session works there throughnextProxyCookies(request, response).- A session read is dynamic. With
cacheComponentson, the part of the page that reads it belongs in a<Suspense>boundary, and never inside ause cachefunction.