Skip to content

Commit

Permalink
Added example for setting cookie before redirect in middleware (#32542)
Browse files Browse the repository at this point in the history
  • Loading branch information
molebox authored Dec 21, 2021
1 parent 738a964 commit 4f67edd
Showing 1 changed file with 74 additions and 2 deletions.
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
- `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
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

0 comments on commit 4f67edd

Please sign in to comment.