Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 188 additions & 0 deletions docs/1.guide/2.routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ This behaviour can be overridden by some request properties (e.g.: `Accept` or `
Nitro allows you to add logic at the top-level for each route of your configuration. It can be used for redirecting, proxying, caching and adding headers to routes.

It is a map from route pattern (following [radix3](https://github.com/unjs/rou3/tree/radix3#route-matcher)) to route options.
All matching rules are deep‑merged with specificity precedence (more specific patterns override less specific), and matching is based on the path only (no query string).

When `cache` option is set, handlers matching pattern will be automatically wrapped with `defineCachedEventHandler`. See the [cache guide](/guide/cache) to learn more about this function.

Expand Down Expand Up @@ -318,3 +319,190 @@ export default defineNuxtConfig({
})
```
::

::note
Nuxt adds additional route rules such as `ssr`, `noScripts`, and `appMiddleware` that affect HTML rendering behavior inside the Vue app. See Nuxt docs for details.
::

#### Cache

Server-side response caching for matching routes. If set to `false`, disables server-side caching. See: [Cache guide](/guide/cache)

**Example:**

::code-group
```ts [nitro.config.ts]
export default defineNitroConfig({
routeRules: {
'/**': { cache: { swr: true, maxAge: 60 } }
}
})
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/**': { cache: { swr: true, maxAge: 60 } }
}
})
```
::

::note
Shortcut: `swr` below sets `cache: { swr: true, maxAge?: number }`.
::

#### Headers

An object of response headers to set for matching routes.

**Example:**

::code-group
```ts [nitro.config.ts]
export default defineNitroConfig({
routeRules: {
'/**': { headers: {
"Cross-Origin-Resource-Policy": "same-site",
"Cross-Origin-Embedder-Policy": "require-corp",
"Cross-Origin-Opener-Policy": "same-origin"
}
}
}
})
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/**': { headers: {
"Cross-Origin-Resource-Policy": "same-site",
"Cross-Origin-Embedder-Policy": "require-corp",
"Cross-Origin-Opener-Policy": "same-origin"
}
}
}
})
```
::

#### Redirect

Server-side redirect. A plain string uses status code 307 by default.
If the rule key ends with `/**` and `to` also ends with `/**`, the matched tail of the path is appended to `to`. Query params are preserved when the destination is not a wildcard pattern.

**Example:**

::code-group
```ts [nitro.config.ts]
export default defineNitroConfig({
routeRules: {
'/foo': { redirect: '/bar' },
'baz/**': { redirect: { to: '/qux/**', statusCode: 301 } }
}
})
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/foo': { redirect: '/bar' },
'baz/**': { redirect: { to: '/qux/**', statusCode: 301 } }
}
})
```
::


#### Prerender

Adds exact paths to the prerender queue at build time so they are emitted as static assets.


**Example:**

::code-group
```ts [nitro.config.ts]
export default defineNitroConfig({
routeRules: {
'/': { prerender: true }
}
})
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }
}
})
```
::

#### Proxy

Proxies matching requests to another origin or internal path.
If the rule key ends with `/**` and `to` also ends with `/**`, the matched tail of the path is appended to `to`. Query params are preserved when the destination is not a wildcard pattern.
For proxy options, see [H3](https://github.com/h3js/h3/blob/ec77d6bc148e4ff7629ba56577697055cc0fcf2e/src/utils/proxy.ts#L11).


**Example:**

::code-group
```ts [nitro.config.ts]
export default defineNitroConfig({
routeRules: {
'/proxy': { proxy: "/foo" },
'/stream/**': { proxy: { to: '/api/**', streamRequest: true } }
}
})
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
routeRules: {
'/proxy': { proxy: "/foo" },
'/stream/**': { proxy: { to: '/api/**', streamRequest: true } }
}
})
```
::

#### ISR

Incremental Static Regeneration semantics on supported platforms (e.g., Netlify, Vercel). Platform presets map this to native rules/headers where available.
On platforms without native support, behavior may fall back to HTTP cache headers.


::code-group
```ts [nitro.config.ts]
export default defineNitroConfig({
routeRules: {
'/docs/**': { isr: 60 },
}
})
```

```ts [nuxt.config.ts]
export default defineNitroConfig({
routeRules: {
'/docs/**': { isr: 60 },
}
})
```
::

#### Shortcuts

##### Cors

Adds permissive CORS headers. You can override or extend with `headers`.

##### SWR

Shortcut for `cache: { swr: true, maxAge?: number }`. Prefer `isr` on platforms with native support.

##### Static

Legacy alias primarily for older platform integrations. Prefer `isr` going forward.

16 changes: 16 additions & 0 deletions docs/3.config/0.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ export default defineNitroErrorHandler((error, event) => {

Route options. It is a map from route pattern (following [radix3](https://github.com/unjs/rou3/tree/radix3#route-matcher)) to route options.

How matching and precedence work:
- Nitro matches the incoming path against all patterns and deep-merges every matching rule.
- More specific matches override less specific ones. For example, `/blog/post` overrides `/blog/**`, which overrides `/**`.
- The match is performed against the path only (without the query string) and without the configured `app.baseURL`.

When `cache` option is set, handlers matching pattern will be automatically wrapped with `defineCachedEventHandler`.

See the [Cache API](/guide/cache) for all available cache options.
Expand All @@ -371,6 +376,17 @@ See the [Cache API](/guide/cache) for all available cache options.
`swr: true|number` is shortcut for `cache: { swr: true, maxAge: number }`
::

Available keys (summary):
- `cache`: CachedEventHandlerOptions | false β€” server-side caching (see Cache guide)
- `headers`: Record<string,string> β€” set response headers
- `redirect`: string | { to; statusCode? } β€” server redirect; wildcard `/**` tail can be appended to destination; query params are preserved when the destination is not a wildcard pattern
- `prerender`: boolean β€” add exact routes to prerender queue at build; `false` explicitly disables
- `proxy`: string | { to } & ProxyOptions β€” proxy requests; wildcard `/**` tail can be appended to destination; query params are preserved when the destination is not a wildcard pattern
- `isr`: number | boolean | object β€” ISR/Revalidation on supported platforms
- `cors`: boolean β€” shortcut to add permissive CORS headers
- `swr`: boolean | number β€” legacy shortcut for `cache: { swr: true, maxAge? }`
- `static`: boolean | number β€” legacy alias; prefer `isr`

**Example:**

```js
Expand Down
137 changes: 135 additions & 2 deletions src/types/route-rules.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,156 @@
import type { ProxyOptions, RouterMethod } from "h3";
import type { ProxyOptions } from "h3";
import type { ExcludeFunctions, IntRange } from "./_utils";
import type { CachedEventHandlerOptions } from "./runtime";

/**
* Valid HTTP status code range.
*/
export type HTTPStatusCode = IntRange<100, 600>;

/**
* Route rule options that can be applied to matching route patterns.
*
* These options are resolved and merged for every incoming request using radix3
* pattern matching (against the path portion without the configured app.baseURL).
* Some options are shortcuts and will be normalized into other properties
* (see {@link NitroRouteRules}).
*
* @see https://nitro.build/guide/routing#route-rules
*/
export interface NitroRouteConfig {
/**
* Server-side response caching controls.
*
* - When set to an object, matching handlers are wrapped with
* `defineCachedEventHandler` using the provided options.
* - When set to `false`, server-side caching is disabled for matching routes.
*
* @remarks
* The {@link NitroRouteConfig.swr | swr} shortcut below is equivalent to
* `cache: { swr: true, maxAge?: number }`.
*
* @see https://nitro.build/guide/cache
*/
cache?: ExcludeFunctions<CachedEventHandlerOptions> | false;

/**
* Response headers to set for matching routes.
*
* @example
* ```ts
* headers: {
* 'cache-control': 's-maxage=600, stale-while-revalidate=86400'
* }
* ```
*/
headers?: Record<string, string>;

/**
* Server-side redirect for matching routes.
*
* You can specify:
* - A string destination (defaults to status code 307), or
* - An object with `to` and an optional `statusCode`.
*
* Wildcard behavior:
* - When the rule key ends with `/**`, the matched path (minus the base) will be appended to the `to` if it also ends with `/**`.
* - Query parameters from the incoming request are preserved when `to` is not a wildcard pattern.
*
* @example
* ```ts
* redirect: '/new-page' // 307 by default
* // or
* redirect: { to: '/new-page/**', statusCode: 301 }
* ```
*/
redirect?: string | { to: string; statusCode?: HTTPStatusCode };

/**
* Include this route in the prerendering queue at build time.
*
* @remarks
* - Only exact paths (no wildcards) are collected automatically into the
* prerender list.
* - Wildcard rules still apply at runtime but are not auto-added to the
* prerender queue.
* - Set to `false` on a matching rule to explicitly disable prerendering for
* that route.
*
* @see https://nitro.build/config#prerender
*/
prerender?: boolean;

/**
* Forward matching requests to another origin or internal endpoint.
*
* You can specify:
* - A string destination, or
* - An object with `to` and any additional `h3` ProxyOptions (e.g. headers, changeOrigin, etc.).
*
* Wildcard behavior:
* - When the rule key ends with `/**`, the matched path (minus the base) will be appended to `to` if it also ends with `/**`.
* - Query parameters from the incoming request are preserved when `to` is not a wildcard pattern.
*
* @see h3 ProxyOptions: https://github.com/h3js/h3/blob/ec77d6bc148e4ff7629ba56577697055cc0fcf2e/src/utils/proxy.ts#L11
*/
proxy?: string | ({ to: string } & ProxyOptions);

/**
* Incremental Static Regeneration (ISR) / Stale-While-Revalidate semantics on supported platforms.
*
* - `number`: revalidation time in seconds.
* - `true`: never expires until the next deployment.
* - `false`: disable ISR for this route.
*
* Platform notes:
* - Platform presets (e.g., Vercel/Netlify) map this option to native rules or headers as appropriate.
* - On platforms without native support, behavior may fall back to HTTP cache headers.
*/
isr?: number /* expiration */ | boolean | VercelISRConfig;

// Shortcuts
//_________________________________Shortcuts_________________________________

/**
* Shortcut to add permissive CORS headers.
*
* Adds defaults:
* - `access-control-allow-origin: "*"`
* - `access-control-allow-methods: "*"`
* - `access-control-allow-headers: "*"`
* - `access-control-max-age: "0"`
*
* You can override or extend with an explicit {@link NitroRouteConfig.headers | headers} rule.
*/
cors?: boolean;
/**
* Shortcut for server cache SWR behavior.
*
* - `true`: enable SWR with default TTL (no `maxAge` set).
* - `number`: shorthand for `cache: { swr: true, maxAge: <number> }`.
*
* Legacy note:
* - On platforms with native ISR (e.g., Vercel/Netlify), prefer `isr` for full platform integration.
*/
swr?: boolean | number;
/**
* Legacy alias primarily used by platform presets (e.g., Vercel) historically.
*
* - In Vercel integration, `static: true` was treated similarly to `isr: false`.
* - Prefer using `isr` directly for clarity and platform support.
*
* This field is kept for backwards compatibility and may be ignored in core normalization.
*/
static?: boolean | number;
}

/**
* Normalized route rules that Nitro uses at runtime after resolving shortcuts.
*
* Differences from NitroRouteConfig:
* - `redirect` is always an object `{ to, statusCode }`.
* - `proxy` is always an object `{ to, ...ProxyOptions }`.
* - Shortcut fields (`cors`, `swr`, `static`) are omitted after normalization.
*/
export interface NitroRouteRules
extends Omit<NitroRouteConfig, "redirect" | "cors" | "swr" | "static"> {
redirect?: { to: string; statusCode: HTTPStatusCode };
Expand Down