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

Added example for setting cookie before redirect in middleware #32542

Merged
merged 10 commits into from
Dec 21, 2021
76 changes: 74 additions & 2 deletions docs/api-reference/next/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,68 @@ import type { NextFetchEvent } from 'next/server'

## NextResponse

The `NextResponse` object is an extension of the native [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) interface, with the following added methods and properties:
The `NextResponse` class extends the native [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) interface, with the following:

### Public methods

Public methods are available on an instance of the `NextResponse` class. Depending on your use case, you can create an instance and assign to a variable, then access the following public methods:

- `cookies` - An object with the cookies in the `Response`
- `cookie` - Set a cookie in the `Response`
- `cookie()` - Set a cookie in the `Response`
- `clearCookie()` - Accepts a `cookie` and clears it

```ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
// create an instance of the class to access the public methods. This uses `next()`,
// you could use `redirect()` or `rewrite()` as well
let response = NextResponse.next()
// get the cookies from the request
let cookieFromRequest = request.cookies['my-cookie']
// set the `cookie`
response.cookie('hello', 'world')
// set the `cookie` with options
const cookieWithOptions = response.cookie('hello', 'world', {
path: '/',
maxAge: 1000 * 60 * 60 * 24 * 7,
httpOnly: true,
sameSite: 'strict',
domain: 'example.com',
})
// clear the `cookie`
response.clearCookie('hello')

return response
}
```

### Static methods

The following static methods are available on the `NextResponse` class directly:

- `redirect()` - Returns a `NextResponse` with a redirect set
molebox marked this conversation as resolved.
Show resolved Hide resolved
- `rewrite()` - Returns a `NextResponse` with a rewrite set
- `next()` - Returns a `NextResponse` that will continue the middleware chain
- `json()` - A convenience method to create a response that encodes the provided JSON data

```ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(req: NextRequest) {
// if the request is coming from New York, redirect to the home page
if (req.geo.city === 'New York') {
return NextResponse.redirect('/home')
// if the request is coming from London, rewrite to a special page
} else if (req.geo.city === 'London') {
return NextResponse.rewrite('/not-home')
}

return NextResponse.json({ message: 'Hello World!' })
}
```

All methods above return a `NextResponse` object that only takes effect if it's returned in the middleware function.

Expand All @@ -86,6 +141,23 @@ All methods above return a `NextResponse` object that only takes effect if it's
import { NextResponse } from 'next/server'
```

### Setting the cookie before a redirect

In order to set the `cookie` _before_ a redirect, you can create an instance of `NextResponse`, then access the `cookie` method on the instance, before returning the response.

Note that there is a [Chrome bug](https://bugs.chromium.org/p/chromium/issues/detail?id=696204) which means the entire redirect chain **must** be from the same origin, if they are from different origins, then the `cookie` might be missing until a refresh.

```ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(req: NextRequest) {
const res = NextResponse.redirect('/') // creates an actual instance
molebox marked this conversation as resolved.
Show resolved Hide resolved
res.cookie('hello', 'world') // can be called on an instance
return res
}
```

### Why does redirect use 307 and 308?

When using `redirect()` you may notice that the status codes used are `307` for a temporary redirect, and `308` for a permanent redirect. While traditionally a `302` was used for a temporary redirect, and a `301` for a permanent redirect, many browsers changed the request method of the redirect, from a `POST` to `GET` request when using a `302`, regardless of the origins request method.
Expand Down