Skip to main content

Vue Verify and troubleshoot

Troubleshooting

Vite fails to pre-bundle c15t's .vue files

Check. vite dev reports an error from dependency optimization for a .vue file under @c15t/vue, or manifest() throws c15t: manifest() has no backend URL. consentManifest() is missing from the plugins array of vite.config.ts.

Fix. Add consentManifest() from c15t/vue/vite to the plugins array, next to @vitejs/plugin-vue, and set VITE_C15T_BACKEND_URL (or VITE_INTH_PROJECT_URL). See the quickstart.

app.use() throws "pass mode"

Check. The plugin options have no mode. Earlier v3 alphas took backendURL, manifest, manifestURL and manifestSnapshot on the plugin.

Fix. Pass mode: manifest(), hosted() or offline() from c15t/vue/vue-plugin. Move backendURL into the mode, such as hosted({ backendURL }), or let consentManifest() supply it.

Why does the build fail to download the manifest?

Check. vite build stops with an error from consentManifest that starts with the plugin's name, such as @c15t/core/build: could not fetch the consent manifest from <url> during the build. The name is @c15t/core/build for c15t/build and @c15t/vue/vite for c15t/vue/vite. vite dev logs the same message as a warning and keeps going. The part in parentheses names the cause:

MessageCauseFix
fetch failed, with ENOTFOUND, ECONNREFUSED or another network errorThe build cannot reach the backendBuild where the backend is reachable
no response within 10 secondsThe backend did not answer in timeCheck the backend, or build where it is reachable
/manifest responded 404The URL is not your project's backend, such as the https://your-project.inth.app placeholder or a URL missing its path prefixCopy the backend URL exactly as Inth shows it, or set VITE_C15T_BACKEND_URL
/manifest returned an invalid consent manifest.The URL answered with something other than a consent manifest, such as an HTML pagePoint backendURL at the backend itself, not your site or a dashboard page

A failed download never reuses an old snapshot. To deploy while the backend is down, run the build with C15T_ON_BUILD_ERROR=runtime. snapshot is then undefined, and the browser fetches the policy from the backend at runtime.

Only a build that uses manifest() downloads the manifest. The plugin fetches after Vite has dropped the code the app does not use, so a hosted() or offline() build never contacts the backend and never fails this way.

An error or warning that says no backend URL is set means the plugin found no backendURL option and no variable. Set VITE_C15T_BACKEND_URL (or VITE_INTH_PROJECT_URL) in .env or the build environment, or pass the absolute backend URL from your Inth project. The troubleshooting guide lists every message.

A notice that the build skipped the consent manifest fetch means the backend URL is relative, such as /api/c15t. Pass the absolute backend URL instead. With onBuildError: 'fail', this stops the build with build-time manifests require an absolute upstream URL.

Why is snapshot undefined?

Check. snapshot from c15t/generated is undefined, and the browser requests ${backendURL}/manifest on page load.

Fix. snapshot is undefined when Vite has no policy to serve:

  • consentManifest is missing from plugins in vite.config.ts. Without the plugin, c15t/generated still resolves, but exports undefined.
  • The fetch failed in vite dev, or in a build with C15T_ON_BUILD_ERROR=runtime. The terminal shows a could not fetch the consent manifest warning.
  • The backend URL is relative, so the plugin skipped the fetch.
  • consentManifest({ source: 'runtime' }) is set, so the plugin never fetches.

Fix the cause, then restart vite dev or rebuild. The plugin fetches once when Vite starts.

app.use() fails or does nothing

Check. Look at where you import the plugin. c15t/vue is the Nuxt module and is not a Vue plugin.

Fix. Import the plugin from c15t/vue/vue-plugin.

A composable throws "Kernel not found"

Check. The component is outside the app that installed c15tVue, for example in a separate createApp() instance, or the composable ran outside setup.

Fix. Install the plugin on the app that renders the component, and call composables inside setup.

Why is there no banner?

Check. DevTools shows the matched policy. With hosted(), find the /init request in the Network tab; with manifest({ source: 'runtime' }), the /manifest request.

Fix. Work through these causes in order:

  1. The visitor's policy asks for no banner. A policy with prompt none shows no banner, which is common in opt-out regions. See why the banner may be absent.
  2. manifest() resolves the unknown-location policy. Without inputs or geoURL, every visitor gets the policy your project assigns when the location is unknown. Check that rule, then rebuild.
  3. ConsentRoot is inside a route that unmounts. Put it in the root component.
  4. The backend did not answer. With hosted(), /init must return 200; with a runtime manifest, /manifest must. A CORS error means your site's origin is missing from the Inth project's trusted origins. While resolution fails, c15t shows no UI and keeps every optional category denied.
  5. A stored choice exists. Clear the c15t cookie and localStorage entry, or use a private window.

The app throws IABUnavailableError

Check. The error has the code C15T_IAB_UNAVAILABLE and reads "c15t: this visitor's policy uses IAB TCF, but iab is not set." The visitor's policy uses the iab model and the backend sent its vendor list, but the plugin has no iab option, or has iab: false or iab: { enabled: false }. The standard banner does not handle the IAB model, so c15t throws rather than leave the visitor with no consent UI. app.use() throws when the policy arrives with prefetch; otherwise the error is uncaught once the policy resolves, and ConsentRoot renders nothing.

Fix. If the site uses IAB TCF, pass iab to the plugin, such as app.use(c15tVue, { iab: {} }). See IAB TCF. If it does not, remove the iab model from the policy for that region in your Inth project or policy pack. A backend that answers gvl: null turns IAB off for that request, and nothing throws.

Tokens in my CSS do not apply

Check. The c15tVue plugin appends a <style id="c15t-css-vars"> element to <head> when you install it. The element sets every token, including the defaults. A :root rule in your stylesheet for the same variable competes with it on source order, so it may lose.

Fix. Set values through the plugin's tokens option. See customize.

Check. Look for the vendor in both the plugin's scripts and a createScriptLoader call.

Fix. Keep only scripts.

Check. Look for the vendor's own snippet in index.html, or SDK initialization in your code.

Fix. Remove it so c15t is the only loader.

The page flashes without the banner on a server-rendered Vue app

Check. c15t does not support server rendering for plain Vue.

Fix. Use the c15t Nuxt module. See server rendering without Nuxt.

Names from an earlier alpha are missing

Check. An import or component from an earlier v3 alpha fails to resolve, such as c15t/vue/consent-root, ConsentPreferencesLink or the default export of c15t/vue/vite. The v3 alphas removed names that never shipped in a stable release, with no alias.

Fix. Use the current names:

RemovedUse instead
Vue plugin options backendURL, manifest, manifestSnapshot, manifestURL, customFetch, domainmode, a factory from c15t/vue/vue-plugin that takes them
The default c15tVue export of c15t/vue/viteconsentManifest from c15t/vue/vite. The Vue app plugin keeps the name c15tVue.
c15t/vue/consent-root, c15t/vue/consent-widgetNamed exports from c15t/vue/vue-plugin
ConsentPreferencesLink, runtime/components/consent-preferences-link.vueConsentDialogLink, consent-dialog-link.vue
ConsentFrameConsentGate
hosted({ url })hosted({ backendURL }), or VITE_C15T_BACKEND_URL

More help

Troubleshoot consent covers problems shared by every framework, such as a missing banner, analytics that load before a choice, imports that fail because npm installed c15t v2, choices that disappear on reload, server HTML that differs from the browser, static builds that fail and content blockers that hide the consent UI.