Skip to content

Commit

Permalink
docs: supporting after for providers (vercel#73743)
Browse files Browse the repository at this point in the history
Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com>
Co-authored-by: Lee Robinson <me@leerob.io>
  • Loading branch information
3 people authored Dec 11, 2024
1 parent 3b136b6 commit 4d1613d
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions docs/01-app/02-building-your-application/10-deploying/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,67 @@ If you don't need a mix of both static and dynamic components, you can make your

</AppOnly>

<AppOnly>

### `after`

[`after`](/docs/app/api-reference/functions/after) is fully supported when self-hosting with `next start`.

When stopping the server, ensure a graceful shutdown by sending `SIGINT` or `SIGTERM` signals and waiting. This allows the Next.js server to wait until after pending callback functions or promises used inside `after` have finished.

If you want to use `after` on custom infrastructure, check your provider documentation to view support for `after`.

<details id="after-serverless">
<summary>Reference: supporting `after` for serverless platforms</summary>
Using `after` in a serverless context requires waiting for asynchronous tasks to finish after the response has been sent. In Next.js and Vercel, this is achieved using a primitive called `waitUntil(promise)`, which extends the lifetime of a serverless invocation until all promises passed to [`waitUntil`](https://vercel.com/docs/functions/functions-api-reference#waituntil) have settled.

If you want your users to be able to run `after`, you will have to provide your implementation of `waitUntil` that behaves in an analogous way.

When `after` is called, Next.js will access `waitUntil` like this:

```jsx
const RequestContext = globalThis[Symbol.for('@next/request-context')]
const contextValue = RequestContext?.get()
const waitUntil = context?.waitUntil
```
Which means that `globalThis[Symbol.for('@next/request-context')]` is expected to contain an object like this:
```tsx
type NextRequestContext = {
get(): NextRequestContextValue | undefined
}

type NextRequestContextValue = {
waitUntil?: (promise: Promise<any>) => void
}
```
Here is an example of the implementation.
```tsx
import { AsyncLocalStorage } from 'node:async_hooks'

const RequestContextStorage = new AsyncLocalStorage<NextRequestContextValue>()

// Define and inject the accessor that next.js will use
const RequestContext: NextRequestContext = {
get() {
return RequestContextStorage.getStore()
},
}
globalThis[Symbol.for('@next/request-context')] = RequestContext

const handler = (req, res) => {
const contextValue = { waitUntil: YOUR_WAITUNTIL }
// Provide the value
return RequestContextStorage.run(contextValue, () => nextJsHandler(req, res))
}
```
</details>
</AppOnly>
<PagesOnly>
## Manual Graceful Shutdowns
Expand Down

0 comments on commit 4d1613d

Please sign in to comment.