This error occurs when attempting to use Next.js's cookies() function inside a Client Component marked with "use client". The cookies() API is designed exclusively for Server Components, Server Actions, and Route Handlers where HTTP headers can be properly accessed.
This error indicates you're trying to call the Next.js cookies() function from next/headers within a Client Component. The cookies() function is part of Next.js's server-side API that accesses HTTP request cookies during server-side rendering. Client Components execute in the browser where direct access to HTTP headers is not available for security reasons. The cookies() function can read incoming request cookies in Server Components and read/write cookies in Server Actions or Route Handlers. When you mark a component with "use client", it becomes a Client Component that hydrates on the browser side, where the cookies() function cannot operate because it requires access to the HTTP request/response cycle that only exists on the server. This restriction is intentional in Next.js's architecture to maintain a clear separation between server and client execution contexts. Cookies contain sensitive authentication tokens and session data that should be handled securely on the server side, not exposed to client-side JavaScript unless explicitly intended.
The simplest solution is to keep cookie access in Server Components and pass the data as props to Client Components:
// app/components/UserProfile.tsx (Server Component - no "use client")
import { cookies } from 'next/headers';
import ClientDisplay from './ClientDisplay';
export default async function UserProfile() {
const cookieStore = await cookies();
const token = cookieStore.get('auth-token');
return <ClientDisplay token={token?.value} />;
}
// app/components/ClientDisplay.tsx (Client Component)
'use client';
export default function ClientDisplay({ token }: { token?: string }) {
// Use token in client-side logic
return <div>Token: {token}</div>;
}This maintains the security boundary while allowing interactivity in the Client Component.
If you need to set or modify cookies from client-side interactions, create a Server Action:
// app/actions/auth.ts
'use server';
import { cookies } from 'next/headers';
export async function setAuthToken(token: string) {
const cookieStore = await cookies();
cookieStore.set('auth-token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 7 // 1 week
});
}
// app/components/LoginButton.tsx
'use client';
import { setAuthToken } from '../actions/auth';
export default function LoginButton() {
async function handleLogin() {
const token = await fetchToken();
await setAuthToken(token);
}
return <button onClick={handleLogin}>Login</button>;
}Server Actions allow safe cookie modification from client interactions.
For more complex cookie operations, use a Route Handler:
// app/api/auth/route.ts
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';
export async function GET() {
const cookieStore = await cookies();
const token = cookieStore.get('auth-token');
return NextResponse.json({ token: token?.value });
}
export async function POST(request: Request) {
const { token } = await request.json();
const cookieStore = await cookies();
cookieStore.set('auth-token', token, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
return NextResponse.json({ success: true });
}
// app/components/ClientComponent.tsx
'use client';
import { useEffect, useState } from 'react';
export default function ClientComponent() {
const [token, setToken] = useState<string | null>(null);
useEffect(() => {
fetch('/api/auth')
.then(res => res.json())
.then(data => setToken(data.token));
}, []);
return <div>Token: {token}</div>;
}This provides a clean API boundary for client-server cookie communication.
For client-side cookies that don't require server-side security (like UI preferences), use a client-safe library:
npm install js-cookie
# or
npm install cookies-next// app/components/ThemeToggle.tsx
'use client';
import Cookies from 'js-cookie';
import { useState } from 'react';
export default function ThemeToggle() {
const [theme, setTheme] = useState(() => Cookies.get('theme') || 'light');
function toggleTheme() {
const newTheme = theme === 'light' ? 'dark' : 'light';
Cookies.set('theme', newTheme, { expires: 365 });
setTheme(newTheme);
}
return <button onClick={toggleTheme}>{theme} mode</button>;
}IMPORTANT: Never store sensitive data (auth tokens, session IDs) in client-accessible cookies without httpOnly flag.
For page-level cookie access, read cookies in the page Server Component and pass to children:
// app/dashboard/page.tsx
import { cookies } from 'next/headers';
import DashboardClient from './DashboardClient';
export default async function DashboardPage() {
const cookieStore = await cookies();
const userPrefs = cookieStore.get('preferences')?.value;
const sessionId = cookieStore.get('session')?.value;
return (
<DashboardClient
preferences={userPrefs ? JSON.parse(userPrefs) : null}
hasSession={!!sessionId}
/>
);
}
// app/dashboard/DashboardClient.tsx
'use client';
interface Props {
preferences: any;
hasSession: boolean;
}
export default function DashboardClient({ preferences, hasSession }: Props) {
// Client component can use the data without accessing cookies directly
return <div>{hasSession ? 'Logged in' : 'Guest'}</div>;
}This pattern keeps cookie access server-side while enabling full client interactivity.
Check that you haven't accidentally added "use client" where it's not needed:
// BAD: Unnecessary "use client" prevents cookies() usage
'use client'; // Remove this if you don't need interactivity
import { cookies } from 'next/headers';
export default async function ServerComponent() {
const cookieStore = await cookies(); // This will error
// ...
}
// GOOD: Server Component (default)
import { cookies } from 'next/headers';
export default async function ServerComponent() {
const cookieStore = await cookies(); // This works
// ...
}Remember: Server Components are the default in Next.js App Router. Only add "use client" when you need browser APIs, React hooks, or event handlers.
When designing your Next.js application architecture, follow the principle of reading cookies as high up in the component tree as possible (preferably in layout.tsx or page.tsx Server Components) and passing the data down as props. This minimizes the surface area where sensitive cookie data exists and makes security audits easier.
For authentication patterns, consider using Next.js middleware (middleware.ts) to validate cookies before requests reach your components. Middleware can read and modify cookies for all routes, providing a centralized authentication layer.
Be aware that passing cookie values as props to Client Components serializes them into the HTML, making them visible in the browser's page source. Only pass non-sensitive data or identifiers, never raw authentication tokens or session secrets. For sensitive operations, always use Server Actions or Route Handlers.
The cookies() function is async in Next.js 15+, so always await it: const cookieStore = await cookies(). In earlier versions, it was synchronous. Check your Next.js version if you encounter async-related errors.
If you're migrating from Pages Router to App Router, note that getServerSideProps patterns need to be refactored into Server Components or Server Actions. The cookies API works differently between the two routing paradigms.
For testing, mock the cookies() function in your test environment since it only works in Next.js server contexts. Use libraries like next-test-api-route-handler for integration testing Route Handlers that use cookies.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite