# Configuration

Rebask has two configuration sources. `rebask()` in `vite.config.ts` sets build-time options, and
`rebask.config.ts` is read by the server at runtime.

## `rebask()`

Pass options to `rebask()` in `vite.config.ts`:

```ts
import { rebask } from "@rebask/core/vite"

rebask({
  prerender: true,
  dedupeFetch: true,
  fullHtmlForBots: false,
})
```

### `prerender`

```ts
rebask({ prerender: true })
```

[Prerender static routes](./caching/page-caching.md) at build time. Enabled by default.

A route that was expected to be static but renders dynamically fails the build by default. Set
`failOnDynamic` to `false` to log a warning instead:

```ts
rebask({ prerender: { failOnDynamic: false } })
```

> Leave both enabled. Disabling `prerender` skips static shells, and disabling `failOnDynamic` lets
> routes go dynamic with only a build warning, losing PPR caching.

### `deploymentId`

```ts
rebask({ deploymentId: process.env.DEPLOYMENT_ID })
```

Set a stable identifier for the current deployment, used for
[skew protection](./production/skew-protection.md). When omitted, Rebask generates a fresh id on each
production build, so a mismatch means the client is on a stale deployment.

### `configPath`

```ts
rebask({ configPath: "./rebask.config.ts" })
```

Set the path to your `rebask.config.ts`. Relative paths resolve from the project root. When omitted,
Rebask auto-detects `rebask.config.{ts,mts,mjs,js}` in the project root.

### `dedupeFetch`

```ts
rebask({ dedupeFetch: true })
```

[Deduplicate identical safe `fetch` requests](./caching/server-components.md#fetching-in-server-components) within a single incoming request. Enabled by default.
Only `GET` and `HEAD` requests are deduplicated, and passing `signal` to a `fetch` call opts that
request out.

### `fullHtmlForBots`

```ts
rebask({ fullHtmlForBots: false })
```

Wait for the full HTML instead of streaming [Suspense fallbacks](./rendering/ppr.md#suspense-and-dynamic-work)
for crawler document requests.

Disabled by default because it makes crawler responses slower: the server waits for the whole page
to resolve instead of streaming a shell right away.

### `markdownUrls`

```ts
rebask({ markdownUrls: true })
```

Serve routes with a `markdown.md` or `markdown.ts` file at their `.md` URL in addition to
`Accept: text/markdown`. Enabled by default. Set to `false` to disable `.md` URLs. See
[Agents](./agents.md#markdown) to learn more.

### `clientTraceMetadata`

```ts
rebask({ clientTraceMetadata: ["traceparent"] })
```

Header names to expose to the browser so client navigations, prefetch, and Server Function requests
continue the server trace. Defaults to an empty list.

See [Telemetry](./telemetry.md) for SDK setup and emitted spans and metrics.

### `proxyTimeout`

```ts
rebask({ proxyTimeout: 30_000 })
```

Set the timeout in milliseconds for [external proxy rewrites](./routing/proxy.md#external-rewrites).
Defaults to 30 seconds. Set to `null` to disable.

### `shellPrerenderTimeout`

```ts
rebask({ shellPrerenderTimeout: 30_000 })
```

Set how long in milliseconds a build prerender, upgrade, or
[background shell render](./caching/page-caching.md#page-cache-layers-pathname-shells) waits for pending work before
postponing the rest. Defaults to 30 seconds.

## Dependencies that import React

Vite externalizes dependencies in the SSR environment by default. An externalized package that
imports React resolves its own copy through Node instead of Vite's dedupe, which can produce an
`Invalid hook call` error during SSR. Bundle that package instead:

```ts
// vite.config.ts
export default defineConfig({
  plugins: [rsc(), react(), rebask()],
  ssr: { noExternal: ["eve"] },
})
```

## `rebask.config.ts`

Runtime configuration lives in `rebask.config.ts`. Every option is optional:

```ts
import type { RebaskConfig } from "@rebask/core"

export default {} satisfies RebaskConfig
```

### `cacheHandler`

Set the [`CacheStorage`](./caching/cache-handler.md#cachestorage) implementation Rebask uses for
server cache entries. Production defaults to a filesystem cache with an in-memory LRU. Development
uses a no-op cache. Platform adapters may supply their own handler:

```ts
import type { RebaskConfig } from "@rebask/core"
import { CustomCacheHandler } from "./custom-handler"

export default {
  cacheHandler: new CustomCacheHandler(),
} satisfies RebaskConfig
```

If you want to change the default cache handler, extending `BaseCacheStorage` is recommended.

### `serverFunctions`

```ts
export default {
  serverFunctions: {
    allowedOrigins: [],
    allowedForwardedHosts: [],
    bodySizeLimit: 1024 * 1024,
  },
} satisfies RebaskConfig
```

Configure security and runtime controls for [Server Functions](./server-functions.md):

| Option                  | Type       | Purpose                                                                                                                          |
| ----------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `allowedOrigins`        | `string[]` | Hostnames allowed to invoke Server Functions cross-origin, compared against the `host` portion of the request's `Origin` header. |
| `allowedForwardedHosts` | `string[]` | Hostnames trusted to appear in `X-Forwarded-Host`, used in place of `Host` for the origin comparison.                            |
| `bodySizeLimit`         | `number`   | Maximum Server Function request body size in bytes. Requests over the limit receive a `413`. Defaults to 1 M.B                   |

Each `allowedOrigins` and `allowedForwardedHosts` entry is a bare host without a scheme, such as
`example.com` or `localhost:3000`, and supports `*.example.com` and `**.example.com` wildcards.

An empty `allowedOrigins` accepts only same-origin requests. An empty `allowedForwardedHosts` ignores
`X-Forwarded-Host`.
