---
title: Nuxt
description: The build fetches your public policy once and bundles it, so the
  server never fetches it at runtime.
lastModified: "2026-10-10T14:59:21+01:00"
lastAuthor: Kaylee
---
The build fetches your public policy once and bundles it, so the server never
fetches it at runtime.

The default mode, `manifest()`, bundles the manifest. The module reads
`NUXT_PUBLIC_C15T_BACKEND_URL`, then `NUXT_PUBLIC_INTH_PROJECT_URL`, when the
`c15t` key sets no `backendURL`, so
`nuxt.config.ts` needs only the module:

```ts title="nuxt.config.ts"
export default defineNuxtConfig({
	compatibilityDate: '2026-07-04',
	modules: ['c15t/vue'],
});
```

The module fetches the snapshot during `nuxt build` and when `nuxt dev`
starts, and embeds it in the server bundle. `nuxt prepare` does not fetch, so
dependency installation and type generation do not need the backend. The
consent route and the server render read the snapshot; it stays out of
runtime config and out of the browser bundle. Only
`manifest({ resolve: 'browser' })` adds it to the browser bundle, because the
browser then resolves the policy itself. Production server startup does not
fetch another manifest.

The module skips the fetch for `manifest({ source: 'runtime' })`, a
`manifest({ snapshot })` you supply, and the `hosted()` and `offline()`
modes. A relative backend URL is also skipped, unless `onBuildError` is
`'fail'`.

The snapshot is fixed at build time:

* Rebuild after changing policies, translations or vendors. If your CI caches
  build output, force a fresh build.
* Consent choices still go to the backend.

The build reads the backend URL from your public backend URL variable when
the config doesn't pass one: `NEXT_PUBLIC_C15T_BACKEND_URL` in Next.js,
`NUXT_PUBLIC_C15T_BACKEND_URL` in Nuxt, `PUBLIC_C15T_BACKEND_URL` in Astro,
Svelte and SvelteKit, and `VITE_C15T_BACKEND_URL` in TanStack Start and other
Vite apps. Each also reads the matching Inth variable, such as
`NEXT_PUBLIC_INTH_PROJECT_URL`, when the c15t one is unset. See
[set the backend URL](/docs/concepts/modes#set-the-backend-url).

The fetch waits at most 10 seconds. When it fails, or no backend URL is set,
every framework does the same thing:

|Command|Default when the fetch fails|
|--|--|
|Production build: `next build`, `vite build`, `nuxt build`, `astro build`|The build stops with an error.|
|Dev: `next dev`, `vite dev`, `nuxt dev`, `astro dev`|A warning, and the server fetches the policy at runtime.|

Set `onBuildError` to use one behaviour for both. `'fail'` stops dev too.
`'runtime'` lets a production build finish, and the server fetches the policy
at runtime. The `C15T_ON_BUILD_ERROR` environment variable overrides the
option, so you can deploy during a backend outage without a code change:

```sh
C15T_ON_BUILD_ERROR=runtime npm run build
```

Turborepo's strict environment mode hides undeclared variables from tasks, so
list `C15T_ON_BUILD_ERROR` in the build task's `passThroughEnv` there.

The build skips the fetch, without an error, when it can't use a snapshot,
for example when the backend URL is relative. With `onBuildError: 'fail'`, a
relative URL stops the build. [Consent modes](/docs/concepts/modes#what-happens-when-the-download-fails)
lists every case.

Set `onBuildError` under the `c15t` key in `nuxt.config.ts`. In dev, and in a
build with `onBuildError: 'runtime'`, a failed fetch leaves the server without
a snapshot, and the server fetches and caches the policy at runtime.

For policy updates without a rebuild, set `mode: manifest({ source: 'runtime' })`.
The server then fetches and caches the policy at runtime, and refreshes it
in the background.
