Skip to main content

Nuxt Advanced

Content Security Policy

What c15t adds to the page

A Nuxt app with c15t adds these to the page, and your policy must allow them:

WhatDirective
The <style id="c15t-css-vars"> tag with your theme tokens, in the page headstyle-src
The components' CSS: inline <style> tags Nuxt writes for the server-rendered banner, and stylesheets Nuxt bundles with your appstyle-src
On ssr: false pages in hosted() mode, an inline <script> in the page head that starts /initscript-src
On server-rendered pages with a banner, an inline <script> before its buttons that holds a tap made before hydrationscript-src
Browser requests to /api/c15t/init and /api/c15t/manifest in the default manifest() modeconnect-src 'self'
Consent saves to your backend's /subjects, plus /init in hosted() modeconnect-src
Chunks Nuxt splits out, such as the browser resolver with manifest({ resolve: 'browser' }) and the copy for a language other than Englishscript-src 'self'
<script> elements the script loader creates for scriptsscript-src
Scripts, frames, images and requests your vendors loadscript-src, frame-src, img-src, connect-src for each vendor

Nuxt adds its own inline scripts and, by default, inline styles. Its documentation and modules such as nuxt-security cover those. The banner's first paint uses Nuxt's inline styles. If your policy cannot allow them, turn them off with features: { inlineStyles: false } in nuxt.config.ts: Nuxt then links the banner's CSS as stylesheets, and the module leaves those links in place.

Allow the theme token style tag

The module writes the tokens option into an inline <style id="c15t-css-vars"> tag on every page. A style-src without 'unsafe-inline' blocks it, and the banner falls back to the default theme. The tag's content is the same for every visitor and only changes when you change tokens, so you can allow it with a hash:

  1. Load a page with the policy enforced.
  2. Copy the sha256-... value from the browser's Refused to apply inline style console error.
  3. Add it to style-src and redeploy.

Recompute the hash whenever you change tokens. When you set the module's nonce option, the tag carries that nonce, so a style-src that lists the same nonce allows it. When your policy already allows 'unsafe-inline' for Nuxt's own styles, the tag needs nothing more.

Allow the early init script

On a page with ssr: false in hosted() mode, the module writes an inline <script> into the page head that requests your backend's /init before the app's JavaScript loads. A script-src without 'unsafe-inline' blocks it, and the app then sends its own /init request after it loads, as it would without the script.

  • With nuxt-security, the script carries its per-request nonce. Nothing more is needed.
  • With the module's nonce option, the script carries that nonce.
  • With a hash-based policy, the script's content is the same for every visitor and changes only when you change backendURL or upgrade c15t. Copy the sha256-... value from the browser's Refused to execute inline script console error and add it to script-src.

To leave the script out, set initPrefetch: false in the module options.

A server-rendered banner also writes an inline <script> before its buttons. It holds a tap the visitor makes before the app hydrates. It carries the module's nonce option when set, and its content is the same for every visitor, so a hash works too. If your policy blocks it, the banner still works after hydration, but a tap before then does nothing.

Allow the backend

In the default manifest() mode the browser calls your own origin for /api/c15t/init, which 'self' covers, and sends consent saves to your backend. Add the backend's origin to connect-src. A manifestURL or geoURL on another origin needs that origin too. With iab set and an IAB TCF policy, the browser loads the Global Vendor List through the module's consent route in manifest() mode, or from your backend otherwise.

Content-Security-Policy (partial)
connect-src 'self' https://<your-backend-host>;

Use the host from your Inth project or your self-hosted backend. Requests the Nuxt server makes during rendering are not subject to the browser's policy.

Allow scripts

List each vendor's script host in script-src. The integration guide for each vendor names its hosts.

The module's nonce option adds a nonce to every script the loader creates. Module options and app.config.ts are fixed when the app builds, so every response gets the same value. A nonce only protects a page when it changes on each response, so prefer the host allowlist for c15t's scripts.

Verify

Enforce the policy, not report-only, and load a page. The banner shows your token colors, and the console shows no Refused to apply inline style, Refused to connect or Refused to load the script error that mentions a c15t element, your backend or a vendor you allowed. Click Accept All, and the vendor scripts load. The save to /subjects succeeds.