Cookies in Next.js — Overview, Client & Server Usage
Overview
Cookies are small pieces of data stored on the client’s browser that are sent with every HTTP request to the server. They are commonly used for:
- Authentication & sessions – keeping users logged in.
- Preferences – storing language, theme, or other settings.
- Tracking & analytics – remembering user behavior or visits.
Cookies vs Local Storage
| Feature | Cookies | Local Storage |
|---|---|---|
| Sent to Server | Automatically with every HTTP request | Not sent to server |
| Storage Limit | ~4 KB per cookie | 5–10 MB per domain |
| Expiration | Can set expiry or session-only | Persistent until manually cleared |
| Security | Can be HttpOnly, Secure, SameSite | Accessible via JS, less secure |
| Use Case | Authentication, server-side reading | Client-side data, caching, temporary state |
How Cookies Work
- Client → Server: Browser sends cookies in the
Cookieheader with each request. - Server → Client: Server sets/updates cookies using the
Set-Cookieheader. - Browser stores cookie: Browser automatically stores cookies and sends them on subsequent requests.
Example of headers:
Client Request:
GET /dashboard HTTP/1.1
Host: example.com
Cookie: sessionId=abc123; theme=dark
Server Response:
HTTP/1.1 200 OK
Set-Cookie: sessionId=xyz789; HttpOnly; Path=/; Max-Age=3600Client-Side Cookies
Using native JS
// Set a cookie
document.cookie = "theme=dark; path=/; max-age=3600";
// Read cookies
console.log(document.cookie); // "theme=dark"Using js-cookie
import Cookies from 'js-cookie';
// Set a cookie
Cookies.set('theme', 'dark', { expires: 1 });
// Read a cookie
console.log(Cookies.get('theme')); // "dark"
// Remove a cookie
Cookies.remove('theme');Using useCookieState (ahooks)
type State = string | undefined;
type SetState = (
newValue?: State | ((prevState?: State) => State),
options?: Cookies.CookieAttributes,
) => void;
const [state, setState]: [State, SetState] = useCookieState(
// The key of Cookie
cookieKey: string,
// Optional. Cookie configuration
options?: Options,
);⚠️ Note: These packages do not work server-side because they rely on
document.cookie, which is only available in the browser.
Cookie Options
| Option | Description | Example |
|---|---|---|
path | The URL path the cookie belongs to. Only requests under this path send the cookie. | path='/' (accessible on entire site) |
domain | The domain the cookie is valid for. | domain='.example.com' (subdomains included) |
maxAge | Number of seconds until the cookie expires. | maxAge=3600 (1 hour) |
expires | Absolute date/time for expiration. Overrides maxAge. | expires=new Date(Date.now()+3600000) |
secure | Cookie is only sent over HTTPS. | secure=true |
httpOnly | Cookie cannot be accessed via JavaScript (prevents XSS). | httpOnly=true |
sameSite | Controls cross-site request sending. Values: Strict, Lax, None. | sameSite='Lax' |
overwrite | Overwrites existing cookie with the same name. | overwrite=true |
⚠️ Setting
HttpOnlyandSecureis recommended for sensitive data (like session IDs).
Server-Side Cookies
Next.js allows modifying cookies only in Route Handlers or Server Actions because these run on the server and have access to the request/response lifecycle.
Example: Route Handler
// app/api/set-cookie/route.ts
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';
export async function GET() {
const cookieStore = cookies();
cookieStore.set('theme', 'dark', { path: '/', maxAge: 3600 });
return NextResponse.json({ message: 'Cookie set!' });
}Example: Server Action
'use server';
import { cookies } from 'next/headers';
export async function setThemeCookie(theme: string) {
cookies().set('theme', theme, { path: '/', maxAge: 3600 });
}⚠️ Setting cookies in a normal server function or client function won’t work because Next.js only allows modifying cookies in the request/response context (Route Handlers or Server Actions).
Passing Cookies Manually
Sometimes you need to pass cookies with fetch requests manually:
const res = await fetch('https://example.com/api/data', {
headers: {
Cookie: 'sessionId=abc123'
}
});References
For the most up-to-date and detailed information, please refer to the official documentation:
Summary
- Cookies store small pieces of data on the client and can be sent to the server automatically.
- Use cookies for authentication, sessions, preferences, and analytics.
- Client-side: Use
document.cookieor libraries likejs-cookieoruse-cookie. - Server-side: Only set/modify cookies in Route Handlers or Server Actions in Next.js.
- Local Storage is client-only and larger, while cookies are smaller but can be accessed server-side.
- Always consider security flags like
HttpOnly,Secure, andSameSitewhen working with cookies.