Next.js Cookies Not Working
If you are building authentication, sessions, JWT login, or user tracking in Next.js, you will eventually face one common issue:
Next.js cookies not working
This problem is extremely common, especially when using:
- Next.js App Router
- API Routes
- JWT Authentication
- Apollo Server
- Express.js Backend
- Cross-domain authentication
- Middleware
- HttpOnly cookies
- Production deployment
Sometimes cookies work in the browser but not in Postman.
Sometimes they work locally but fail in production.
Sometimes the cookie is visible in DevTools but not accessible in the server.
In this guide, you will learn:
- Why Next.js cookies are not working
- How cookies work in Next.js
- Common mistakes developers make
- How to fix cookie problems step-by-step
- Best practices for production applications
- Examples using Node.js, Express, Apollo Server, and Next.js
This guide is beginner-friendly and optimized for SEO and readability.
What Are Cookies in Next.js?
Cookies are small pieces of data stored in the browser.
They are commonly used for:
- Authentication
- JWT tokens
- Session management
- User preferences
- Tracking logged-in users
In Next.js, cookies are commonly used with:
- Login systems
- NextAuth
- JWT authentication
- Middleware protection
- API authentication
Why Next.js Cookies Not Working?
There are many reasons why cookies fail in Next.js applications.
Here are the most common causes:
| Problem | Description |
|---|---|
| Missing credentials | Browser does not send cookies |
| Wrong SameSite policy | Browser blocks cookie |
| Secure flag issue | Cookie works only on HTTPS |
| Cross-domain requests | Cookies blocked between domains |
| HttpOnly misunderstanding | Cannot access in frontend |
| Missing cookie forwarding | Server-to-server calls lose cookies |
| Wrong domain/path | Browser rejects cookie |
| App Router confusion | Different APIs in App Router |
Understanding these issues is the key to solving the Next.js cookies not working problem.
Understanding Cookie Flow in Next.js
Before fixing cookies, let’s understand how cookies flow.
Browser → Next.js API Route
fetch("/api/user", {
credentials: "include",
});Code language: JavaScript (javascript)The browser automatically sends cookies.
Next.js API Route → Backend Server
This is where many developers make mistakes.
Cookies are NOT automatically forwarded.
You must manually forward them.
Example:
const cookieHeader = req.headers.get("cookie");
await fetch("http://localhost:5000/user", {
headers: {
cookie: cookieHeader || "",
},
});Code language: JavaScript (javascript)This is one of the biggest reasons behind:
Next.js cookies not working
Setting Cookies in Next.js App Router
In Next.js App Router, use cookies() from next/headers.
Example: Setting Cookie
import { cookies } from "next/headers";
export async function GET() {
cookies().set("token", "abc123", {
httpOnly: true,
secure: true,
sameSite: "lax",
path: "/",
});
return Response.json({
message: "Cookie set successfully",
});
}Code language: JavaScript (javascript)Reading Cookies in Next.js
Example
import { cookies } from "next/headers";
export async function GET() {
const token = cookies().get("token");
return Response.json({
token,
});
}Code language: JavaScript (javascript)Next.js Cookies Not Working in Fetch Requests
This is one of the most common problems.
By default, fetch does NOT send cookies.
You must include:
credentials: "include"Code language: JavaScript (javascript)Correct Example
await fetch("http://localhost:3000/api/user", {
method: "GET",
credentials: "include",
});Code language: JavaScript (javascript)Next.js Cookies Not Working Across Domains
Suppose:
Frontend:
https://example.comCode language: JavaScript (javascript)Backend:
https://api.example.comCode language: JavaScript (javascript)Cookies may fail because of cross-origin restrictions.
Fix
Use:
sameSite: "none",
secure: trueCode language: JavaScript (javascript)Example:
cookies().set("token", token, {
httpOnly: true,
secure: true,
sameSite: "none",
});Code language: CSS (css)Express.js Cookie Setup
If you use Node.js and Express.js backend with Next.js frontend, you must configure CORS properly.
Install Dependencies
npm install express cors cookie-parserExpress Server Example
import express from "express";
import cors from "cors";
import cookieParser from "cookie-parser";
const app = express();
app.use(cookieParser());
app.use(
cors({
origin: "http://localhost:3000",
credentials: true,
}),
);
app.post("/login", (req, res) => {
res.cookie("token", "jwt_token_here", {
httpOnly: true,
secure: false,
sameSite: "lax",
});
res.json({
success: true,
});
});
app.listen(5000);Code language: JavaScript (javascript)Frontend Fetch Example
await fetch("http://localhost:5000/login", {
method: "POST",
credentials: "include",
});Code language: JavaScript (javascript)Without credentials: "include":
Next.js cookies not working
Apollo Server Cookies Not Working
Many developers use Apollo Server with Next.js.
Cookies often fail because credentials are not enabled.
Apollo Server Setup
app.use(
cors({
origin: "http://localhost:3000",
credentials: true,
}),
);Code language: CSS (css)Apollo Client Setup
const client = new ApolloClient({
uri: "http://localhost:5000/graphql",
credentials: "include",
cache: new InMemoryCache(),
});Code language: JavaScript (javascript)Without this configuration:
Apollo cookies will not work correctly.
HttpOnly Cookies Explained
A very common confusion is:
“I cannot see my cookie in localStorage or JavaScript.”
That is NORMAL for HttpOnly cookies.
Example:
httpOnly: trueCode language: JavaScript (javascript)This protects your JWT token from XSS attacks.
You cannot access HttpOnly cookies using:
document.cookieCode language: JavaScript (javascript)But the browser still sends them automatically.
Next.js Middleware Cookie Example
Middleware is commonly used for route protection.
middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("token");
if (!token) {
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}Code language: JavaScript (javascript)Next.js Cookies Not Working in Production
Many developers say:
“Cookies work locally but fail in production.”
This usually happens because of HTTPS.
Common Production Fix
secure: trueCode language: JavaScript (javascript)Cookies with:
sameSite: "none"Code language: JavaScript (javascript)MUST also use:
secure: trueCode language: JavaScript (javascript)Otherwise browsers block them.
Common Mistakes Developers Make
1. Forgetting credentials: “include”
Wrong:
fetch("/api/user");Code language: JavaScript (javascript)Correct:
fetch("/api/user", {
credentials: "include",
});Code language: JavaScript (javascript)2. Using Wrong SameSite Policy
Wrong for cross-domain:
sameSite: "lax"Code language: JavaScript (javascript)Correct:
sameSite: "none"Code language: JavaScript (javascript)3. Trying to Read HttpOnly Cookie in Frontend
Wrong:
document.cookieCode language: JavaScript (javascript)HttpOnly cookies are server-only.
4. Forgetting CORS credentials
Wrong:
cors({
origin: "*",
});Code language: CSS (css)Correct:
cors({
origin: "http://localhost:3000",
credentials: true,
});Code language: CSS (css)5. Not Forwarding Cookies Server-to-Server
Wrong:
fetch("http://backend/api");Code language: JavaScript (javascript)Correct:
fetch("http://backend/api", {
headers: {
cookie: req.headers.get("cookie") || "",
},
});Code language: JavaScript (javascript)Best Practices for Next.js Cookies
Use HttpOnly Cookies
Always use:
httpOnly: trueCode language: JavaScript (javascript)This improves security.
Use Secure Cookies in Production
secure: process.env.NODE_ENV === "production"Code language: JavaScript (javascript)Use Environment Variables
Never hardcode domains or secrets.
Example:
NEXT_PUBLIC_API_URL=http://localhost:5000Code language: JavaScript (javascript)Use Middleware for Route Protection
Middleware is cleaner and more scalable.
Prefer Cookies Over localStorage for JWT
Cookies are safer because they support:
- HttpOnly
- Secure
- SameSite protection
Debugging Checklist for Next.js Cookies Not Working
Whenever cookies fail, check these:
Browser DevTools
Go to:
Application → CookiesCheck if the cookie exists.
Check Request Headers
Verify:
Cookie:is being sent.
Check Response Headers
Verify:
Set-Cookie:Code language: JavaScript (javascript)exists.
Verify CORS
Backend must allow:
credentials: trueCode language: JavaScript (javascript)Verify HTTPS
Production cookies often require HTTPS.
Complete Authentication Example
Login API Route
import { cookies } from "next/headers";
export async function POST() {
cookies().set("token", "jwt_token", {
httpOnly: true,
secure: false,
sameSite: "lax",
path: "/",
});
return Response.json({
success: true,
});
}Code language: JavaScript (javascript)Protected Route
import { cookies } from "next/headers";
export async function GET() {
const token = cookies().get("token");
if (!token) {
return Response.json(
{ error: "Unauthorized" },
{ status: 401 },
);
}
return Response.json({
message: "Protected route",
});
}Code language: JavaScript (javascript)Conclusion
The Next.js cookies not working issue is extremely common, especially when working with authentication systems, Apollo Server, Express.js, or cross-domain APIs.
Most cookie issues happen because of:
- Missing
credentials: "include" - Wrong
SameSitepolicy - CORS misconfiguration
- Missing HTTPS
- Not forwarding cookies server-to-server
Once you understand how cookies flow between browser, Next.js, and backend APIs, debugging becomes much easier.
If you are building production-grade applications with Next.js, always:
- Use HttpOnly cookies
- Enable credentials properly
- Configure CORS carefully
- Test in production-like environments
- Use middleware for route protection
Mastering cookies is essential for secure authentication and scalable Next.js applications.