Skip to content

cookies

cookies is an async function that allows you to read the HTTP incoming request cookies in Server Component, and read/write outgoing request cookies in Server Actions or Route Handlers.

app/page.tsx
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  const theme = cookieStore.get('theme')
  return '...'
}

Reference

Methods

The following methods are available:

MethodReturn TypeDescription
get('name')ObjectAccepts a cookie name and returns an object with the name and value.
getAll()Array of objectsReturns a list of all the cookies with a matching name.
has('name')BooleanAccepts a cookie name and returns a boolean based on if the cookie exists.
set(name, value, options)-Accepts a cookie name, value, and options and sets the outgoing request cookie.
delete(name)-Accepts a cookie name and deletes the cookie.
clear()-Deletes all cookies.
toString()StringReturns a string representation of the cookies.

Options

When setting a cookie, the following properties from the options object are supported:

OptionTypeDescription
nameStringSpecifies the name of the cookie.
valueStringSpecifies the value to be stored in the cookie.
expiresDateDefines the exact date when the cookie will expire.
maxAgeNumberSets the cookie’s lifespan in seconds.
domainStringSpecifies the domain where the cookie is available.
pathStringLimits the cookie's scope to a specific path within the domain.
secureBoolean,Ensures the cookie is sent only over HTTPS connections for added security.
httpOnlyBooleanRestricts the cookie to HTTP requests, preventing client-side access.
sameSiteBoolean, 'lax', 'strict', 'none'Controls the cookie's cross-site request behavior.
priorityString ("low", "medium", "high")Specifies the cookie's priority
encode('value')FunctionSpecifies a function that will be used to encode a cookie's value.
partitionedBooleanIndicates whether the cookie is partitioned.

To learn more about these options, see the MDN docs.

Good to know

  • cookies is an asynchronous function that returns a promise. You must use async/await or React's use function to access cookies.
    • In version 14 and earlier, cookies was a synchronous function. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future.
  • cookies is a Dynamic API whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into dynamic rendering.
  • The .delete method can only be called:
    • In a Server Action or Route Handler.
    • If it belongs to the same domain from which .set is called. Additionally, the code must be executed on the same protocol (HTTP or HTTPS) as the cookie you want to delete.
  • HTTP does not allow setting cookies after streaming starts, so you must use .set in a Server Action or Route Handler.

Examples

You can use the cookies().get('name') method to get a single cookie:

app/page.tsx
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  const theme = cookieStore.get('theme')
  return '...'
}

Getting all cookies

You can use the cookies().getAll() method to get all cookies with a matching name. If name is unspecified, it returns all the available cookies.

app/page.tsx
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  return cookieStore.getAll().map((cookie) => (
    <div key={cookie.name}>
      <p>Name: {cookie.name}</p>
      <p>Value: {cookie.value}</p>
    </div>
  ))
}

You can use the cookies().set(name, value, options) method in a Server Action or Route Handler to set a cookie. The options object is optional.

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function create(data) {
  const cookieStore = await cookies()
 
  cookieStore().set('name', 'lee')
  // or
  cookieStore().set('name', 'lee', { secure: true })
  // or
  cookieStore().set({
    name: 'name',
    value: 'lee',
    httpOnly: true,
    path: '/',
  })
}

You can use the cookies().has(name) method to check if a cookie exists:

app/page.ts
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  const hasCookie = cookieStore.has('theme')
  return '...'
}

Deleting cookies

There are three ways you can delete a cookie.

Using the delete() method:

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function delete(data) {
  (await cookies()).delete('name')
}

Setting a new cookie with the same name and an empty value:

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function delete(data) {
  (await cookies()).set('name', '')
}

Setting the maxAge to 0 will immediately expire a cookie. maxAge accepts a value in seconds.

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function delete(data) {
  (await cookies()).set('name', 'value', { maxAge: 0 })
}

Version History

VersionChanges
v15.0.0-RCcookies is now an async function. A codemod is available.
v13.0.0cookies introduced.