Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Rewrite cookies page to follow template, add missing methods #69614

Merged
merged 9 commits into from
Sep 3, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ There are two ways you can invalidate the Router Cache:

- In a **Server Action**:
- Revalidating data on-demand by path with ([`revalidatePath`](/docs/app/api-reference/functions/revalidatePath)) or by cache tag with ([`revalidateTag`](/docs/app/api-reference/functions/revalidateTag))
- Using [`cookies.set`](/docs/app/api-reference/functions/cookies#cookiessetname-value-options) or [`cookies.delete`](/docs/app/api-reference/functions/cookies#deleting-cookies) invalidates the Router Cache to prevent routes that use cookies from becoming stale (e.g. authentication).
- Using [`cookies.set`](/docs/app/api-reference/functions/cookies#methods) or [`cookies.delete`](/docs/app/api-reference/functions/cookies#methods) invalidates the Router Cache to prevent routes that use cookies from becoming stale (e.g. authentication).
- Calling [`router.refresh`](/docs/app/api-reference/functions/use-router) will invalidate the Router Cache and make a new request to the server for the current route.

### Opting out
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ description: Examples of popular Next.js UI patterns and use cases.
- [Passing additional values](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#passing-additional-arguments)
- [Revalidating data](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#revalidating-data)
- [Redirecting](/docs/app/building-your-application/data-fetching/server-actions-and-mutations#redirecting)
- [Setting cookies](/docs/app/api-reference/functions/cookies#cookiessetname-value-options)
- [Setting cookies](/docs/app/api-reference/functions/cookies#methods)
- [Deleting cookies](/docs/app/api-reference/functions/cookies#deleting-cookies)

### Metadata
Expand Down
196 changes: 155 additions & 41 deletions docs/02-app/02-api-reference/04-functions/cookies.mdx
Original file line number Diff line number Diff line change
@@ -1,20 +1,90 @@
---
title: cookies
description: API Reference for the cookies function.
related:
title: Next Steps
description: For more information on what to do next, we recommend the following sections
links:
- app/building-your-application/data-fetching/server-actions-and-mutations
---

The `cookies` function allows you to read the HTTP incoming request cookies from a [Server Component](/docs/app/building-your-application/rendering/server-components) or write outgoing request cookies in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).

> **Good to know**: `cookies()` is a **[Dynamic Function](/docs/app/building-your-application/rendering/server-components#dynamic-functions)** whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into **[dynamic rendering](/docs/app/building-your-application/rendering/server-components#dynamic-rendering)** at request time.
```tsx filename="app/page.tsx"
import { cookies } from 'next/headers'

export default function Page() {
const cookieStore = cookies()
const theme = cookieStore.get('theme')
return '...'
}
```

```js filename="app/page.js"
import { cookies } from 'next/headers'

export default function Page() {
const cookieStore = cookies()
const theme = cookieStore.get('theme')
return '...'
}
```

## Reference

### Methods

The following methods are available:

| Method | Return Type | Description |
| --------------------------- | ---------------- | ------------------------------------------------------------------------------- |
| `get('name')` | Object | Accepts a cookie name and returns an object with the name and value. |
| `getAll()` | Array of objects | Returns a list of all the cookies with a matching name. |
| `has('name')` | Boolean | Accepts 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()` | String | Returns a string representation of the cookies. |

### Options

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

| Option | Type | Description |
| ----------------- | -------------------------------------- | ---------------------------------------------------------------------------------- |
| `name` | String | Specifies the name of the cookie. |
| `value` | String | Specifies the value to be stored in the cookie. |
| `expires` | Date | Defines the exact date when the cookie will expire. |
| `maxAge` | Number | Sets the cookie’s lifespan in seconds. |
| `domain` | String | Specifies the domain where the cookie is available. |
| `path` | String | Limits the cookie's scope to a specific path within the domain. |
| `secure` | Boolean, | Ensures the cookie is sent only over HTTPS connections for added security. |
| `httpOnly` | Boolean | Restricts the cookie to HTTP requests, preventing client-side access. |
| `sameSite` | Boolean, `'lax'`, `'strict'`, `'none'` | Controls the cookie's cross-site request behavior. |
| `priority` | String (`"low"`, `"medium"`, `"high"`) | Specifies the cookie's priority |
| `encode('value')` | Function | Specifies a function that will be used to encode a cookie's value. |
| `partitioned` | Boolean | Indicates whether the cookie is [partitioned](https://github.com/privacycg/CHIPS). |

To learn more about these options, see the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies).

## Caveats

- `cookies()` is a **[Dynamic Function](/docs/app/building-your-application/rendering/server-components#dynamic-functions)** whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into **[dynamic rendering](/docs/app/building-your-application/rendering/server-components#dynamic-rendering)**.
- The `.delete()` method can only be called:
- In a [Server Action](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).
- 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](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).

## `cookies().get(name)`
## Examples

A method that takes a cookie name and returns an object with name and value. If a cookie with `name` isn't found, it returns `undefined`. If multiple cookies match, it will only return the first match.
### Getting a cookie

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

```tsx filename="app/page.tsx"
import { cookies } from 'next/headers'

export default function Page() {
const cookieStore = cookies()
const theme = cookieStore.get('theme')
return '...'
}
```

```jsx filename="app/page.js"
import { cookies } from 'next/headers'
Expand All @@ -26,11 +96,11 @@ export default function Page() {
}
```

## `cookies().getAll()`
### Getting all cookies

A method that is similar to `get`, but returns a list of all the cookies with a matching `name`. If `name` is unspecified, it returns all the available 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.

```jsx filename="app/page.js"
```tsx filename="app/page.tsx"
import { cookies } from 'next/headers'

export default function Page() {
Expand All @@ -44,25 +114,42 @@ export default function Page() {
}
```

## `cookies().has(name)`

A method that takes a cookie name and returns a `boolean` based on if the cookie exists (`true`) or not (`false`).

```jsx filename="app/page.js"
import { cookies } from 'next/headers'

export default function Page() {
const cookieStore = cookies()
const hasCookie = cookieStore.has('theme')
return '...'
return cookieStore.getAll().map((cookie) => (
<div key={cookie.name}>
<p>Name: {cookie.name}</p>
<p>Value: {cookie.value}</p>
</div>
))
}
```

## `cookies().set(name, value, options)`
### Setting a cookie

A method that takes a cookie name, value, and options and sets the outgoing request cookie.
You can use the `cookies().set(name, value, options)` method in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers) to set a cookie. The [`options` object](#options) is optional.

> **Good to know**: HTTP does not allow setting cookies after streaming starts, so you must use `.set()` in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).
```tsx filename="app/actions.ts"
'use server'

import { cookies } from 'next/headers'

async function create(data) {
cookies().set('name', 'lee')
// or
cookies().set('name', 'lee', { secure: true })
// or
cookies().set({
name: 'name',
value: 'lee',
httpOnly: true,
path: '/',
})
}
```

```js filename="app/actions.js"
'use server'
Expand All @@ -83,17 +170,37 @@ async function create(data) {
}
```

## Deleting cookies
### Check if a cookie exists

> **Good to know**: You can only delete cookies in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).
You can use the `cookies().has(name)` method to check if a cookie exists:

There are several options for deleting a cookie:
```tsx filename="app/page.ts"
import { cookies } from 'next/headers'

### `cookies().delete(name)`
export default function Page() {
const cookieStore = cookies()
const hasCookie = cookieStore.has('theme')
return '...'
}
```

You can explicitly delete a cookie with a given name.
```jsx filename="app/page.js"
import { cookies } from 'next/headers'

```js filename="app/actions.js"
export default function Page() {
const cookieStore = cookies()
const hasCookie = cookieStore.has('theme')
return '...'
}
```

### Deleting cookies

There are three ways you can delete a cookie.

1. Using the `delete()` method:

```tsx filename="app/actions.ts"
'use server'

import { cookies } from 'next/headers'
Expand All @@ -103,53 +210,60 @@ async function delete(data) {
}
```

### `cookies().set(name, '')`

Alternatively, you can set a new cookie with the same name and an empty value.

```js filename="app/actions.js"
'use server'

import { cookies } from 'next/headers'

async function delete(data) {
cookies().set('name', '')
cookies().delete('name')
}
```

> **Good to know**: `.set()` is only available in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers).
2. Setting a new cookie with the same name and an empty value:

### `cookies().set(name, value, { maxAge: 0 })`
```tsx filename="app/actions.ts"
'use server'

Setting `maxAge` to 0 will immediately expire a cookie. `maxAge` accepts a value in seconds.
import { cookies } from 'next/headers'

async function delete(data) {
cookies().set('name', '')
}
```

```js filename="app/actions.js"
'use server'

import { cookies } from 'next/headers'

async function delete(data) {
cookies().set('name', 'value', { maxAge: 0 })
cookies().set('name', '')
}
```

### `cookies().set(name, value, { expires: timestamp })`
3. Setting the `maxAge` to 0 will immediately expire a cookie. `maxAge` accepts a value in seconds.

Setting `expires` to any value in the past will immediately expire a cookie.
```tsx filename="app/actions.ts"
'use server'

import { cookies } from 'next/headers'

async function delete(data) {
cookies().set('name', 'value', { maxAge: 0 })
}
```

```js filename="app/actions.js"
'use server'

import { cookies } from 'next/headers'

async function delete(data) {
const oneDay = 24 * 60 * 60 * 1000
cookies().set('name', 'value', { expires: Date.now() - oneDay })
cookies().set('name', 'value', { maxAge: 0 })
}
```

> **Good to know**: You can only delete cookies that belong 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.

## Version History

| Version | Changes |
Expand Down
Loading