---
title: "Gateway and status codes"
description: "Configure systhemaGateway for Admin routing, frontend locales and correct not-found responses."
requested_language: fr
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/fr/nextjs/gateway
version: unreleased (main)
docs_index: https://docs.systhema.app/fr/llms.txt
---
> This page isn't translated yet. Showing English.


`systhemaGateway(options)` returns the request handler exported as `proxy` from `src/proxy.ts`. Import it from `@systhemaui/next/gateway`; Payload sites can import the same function from `@systhemaui/payload/gateway`.

## `systhemaGateway`

```ts title="src/proxy.ts"
import { systhemaGateway } from '@systhemaui/next/gateway'

export const proxy = systhemaGateway({ adminRouting: false })
```

Use `adminRouting: false` for Next-only applications. Payload sites normally keep Admin routing enabled:

```ts title="src/proxy.ts"
import { systhemaGateway } from '@systhemaui/payload/gateway'

export const proxy = systhemaGateway({
  customAdminURL: process.env.ADMIN_URL,
})
```

| Option                                                               | Default               | Behavior                                                                                                                                                   |
| -------------------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `adminRouting?: boolean`                                             | `true`                | Reserves the Admin path and enables custom Admin-host routing.                                                                                             |
| `customAdminURL?: string`                                            | Unset                 | Absolute HTTP(S) Admin URL; its hostname identifies the Admin host.                                                                                        |
| `customAdminPath?: string`                                           | `/admin`              | Absolute pathname for the internal Admin route. Trailing slashes are removed; query strings, fragments and `.`/`..` segments are rejected. `/` is allowed. |
| `trustForwardedHost?: boolean`                                       | `false`               | Uses the first `x-forwarded-host` value for Admin-host detection. Enable only behind a proxy that overwrites that header.                                  |
| `locales?: SysthemaLocales                                           | false`                | Injected contract                                                                                                                                          | Overrides the locale contract. `false` disables locale routing. Normally `withSysthema()` supplies `SYSTHEMA_LOCALES` at build time. |
| `localeMiddleware?: (request: NextRequest) => Response \| undefined` | Built-in locale proxy | Advanced override for the locale handler.                                                                                                                  |

Invalid Admin URL or path options throw when constructing the gateway. Host detection uses the trusted forwarded host when enabled, then `Host`, then the request URL hostname. It compares hostnames, not URL paths or ports.

## Request flow

The gateway runs these steps in order:

1. Detect the configured Admin host, the Admin path, Preview and Live Preview. Preview is `__livePreview=true` or the presence of `__previewCollection`.
2. Rewrite anonymous Admin file probes to `/not-found` before excluding asset paths.
3. Pass through infrastructure paths: `/sys`, `/api`, `/trpc`, `/_next`, `/_vercel`, `/favicon.ico`, `/robots.txt`, and paths with a dot in any segment. Prefix matching respects segment boundaries, so `/apiary` is not `/api`.
4. Pass Admin paths through on the Admin host, or when no custom host is configured. On a different host, rewrite them to `/not-found`.
5. On a custom Admin host, rewrite non-Preview page requests under the internal Admin path. For example, `/collections/pages` becomes `/admin/collections/pages`.
6. Run feature handlers, currently frontend locales, and return the first response. Without a handler response, continue to Next.js.
7. Remove entity-tag request revalidation from eligible forwarded page requests.

The gateway reserves no special Admin prefix when `customAdminPath` is `/`. Preview and Live Preview on the custom Admin host fall through to locale handling rather than the Admin rewrite. Domain-routed previews render on the origin they arrived on; moving the iframe across hosts would break its session and live messages. An unsupported explicit `__systhemaPreviewLocale` returns 400.

See [Routing helpers](https://docs.systhema.app/fr/nextjs/locales/routing-helpers.md) for locale proxy behavior and [Frontend locales](https://docs.systhema.app/fr/nextjs/locales.md) for configuration.

## Status codes

The gateway strips `If-None-Match` from forwarded page requests, including rewrites. Next otherwise turns a matching entity tag into 304 even for a cached 404. Removing that request header lets the origin return the actual status and body. It preserves other request headers, including locale middleware overrides, and does not strip the response's `ETag`.

Requests under `/sys`, `/api`, `/trpc`, `/_next` and `/_vercel` retain `If-None-Match`. Responses that neither continue nor rewrite, such as redirects, retain it too. Other asset paths bypass locale routing but are still subject to the forwarding-header rule. `If-Modified-Since` remains available for static-file revalidation.

Anonymous Admin paths with a dot in a segment, such as `/admin/.env` or `/admin/wp-login.php`, rewrite to the site's not-found route. The gateway considers any cookie whose name ends in `-token` a session indicator; it does not authenticate that cookie itself. Requests with that indicator reach Payload.

This guard avoids Payload's anonymous 200 Admin shell for obvious file probes. Unknown Admin paths without a dot, such as `/admin/foo`, can still return 200 anonymously. Payload's `AuthProvider` renders nothing during server rendering before resolving the user, so an Admin `notFound()` or `redirect()` does not establish the response status. The gateway does not look up every CMS page or authenticate every request; your page routes still need to return their own not-found responses.

## Related

- [Public origin](https://docs.systhema.app/fr/nextjs/public-origin.md)
- [Frontend locales](https://docs.systhema.app/fr/nextjs/locales.md)
- [Next.js integration](https://docs.systhema.app/fr/nextjs.md)
