Skip to content

Commit

Permalink
docs: Rewrite cookies page to follow template, add missing methods (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
delbaoliveira authored Sep 3, 2024
1 parent 53596ba commit 9afc84d
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 43 deletions.
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

0 comments on commit 9afc84d

Please sign in to comment.