Usage

Loading scripts on consent, switching language, and reacting to choices.

Usage

Everything is exposed through the injected $consent object and a set of auto-imported composables.

Conditional script loading

Each category exposes a Nuxt Scripts consent trigger named after its key. Pass it straight to useScript:

<script setup lang="ts">
const { $consent } = useNuxtApp()

useScript('https://www.googletagmanager.com/gtag/js?id=G-XXXX', {
  trigger: $consent.triggers.analytics,
})
</script>

The script is only fetched once the user grants consent for that category.

Preferences without a banner (theme, language)

A preference such as the colour mode or the language does not need a banner on the first visit. Nothing is stored until the visitor uses the feature; when they do, the settings modal opens and asks for that one category, and the cookie is written only if they say yes:

  1. First visit — no cookie for the preference, and nothing about it on the banner. If every non-essential cookie works this way, there is no banner at all, only the floating settings button.
  2. The visitor switches the theme or the language — useRequestConsent('preferences') opens the modal with the reason on top.
  3. Yes — the cookie is written and remembered on the next visit. Every later switch goes through without asking.
  4. No — no cookie is written. The language still changes for this visit (switching needs no cookie, remembering it does); the next switch asks again.

Declare each cookie in a category with requiresBanner: false, so it does not force the banner:

nuxt.config.ts
cookieConsent: {
  categories: {
    necessary: { readonly: true },
    preferences: {
      cookies: [
        { id: 'theme_preference', descriptionKey: 'cookies.preferences.theme.description', provider: 'This site', duration: '1 year', requiresBanner: false },
        { id: 'locale_preference', descriptionKey: 'cookies.preferences.locale.description', provider: 'This site', duration: '1 year', requiresBanner: false },
      ],
    },
  },
},

Language — keep it in useConsentCookie: before consent the value lives in memory only, after consent it is written to the cookie.

<script setup lang="ts">
const { $consent } = useNuxtApp()
const locale = useConsentCookie<'en' | 'de'>('locale_preference', 'preferences', { default: () => 'en' })
watch(locale, value => $consent.setLocale(value ?? 'en'), { immediate: true })

async function switchLanguage(next: 'en' | 'de') {
  await useRequestConsent('preferences') // asks only while not granted
  locale.value = next                    // changes either way; stored only with consent
}
</script>

Colour mode — Nuxt's color mode (@nuxtjs/color-mode, included in Nuxt UI) can store the preference in that same cookie. It writes its storage only when the preference changes, so change it only after consent:

nuxt.config.ts
colorMode: { storage: 'cookie', storageKey: 'theme_preference' },
const colorMode = useColorMode()

async function toggleColorMode() {
  if (!(await useRequestConsent('preferences'))) return // declined: no change, no cookie
  colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}

The playground (apps/playground) does exactly this for its colour-mode button and its language switch.

Dynamic language switching

<script setup lang="ts">
const { $consent } = useNuxtApp()
const route = useRoute()

watch(() => route.path, (path) => {
  $consent.setLocale(path.startsWith('/de') ? 'de' : 'en')
}, { immediate: true })
</script>
MemberDescription
stateRef of { [category]: boolean } — the current consent map.
hasMadeChoiceRef<boolean> — whether the user has completed a valid choice.
isModalOpenRef<boolean> — open/close the settings modal.
triggersRecord<category, Promise> — Nuxt Scripts consent triggers.
currentLocaleRef<string> — the active locale.
setLocale(locale)Change the active locale.
setRequestContext(category | null)Set the "just-in-time" context shown in the modal.
updateState(map)Commit a new consent map (always forces necessary: true).

See useRequestConsent to prompt the user at the moment a feature needs a category, and useConsentCookie for cookies that respect consent automatically.

Need a Landing Page?

Modern landing pages with optional modules (blog, docs, forms, i18n). Let's discuss your project.

Build Your MVP

Full-stack SaaS development. Expert in database design, multi-tenancy, and scalable architecture.

Deployment Help

Dockerize your backend, set up CI/CD pipelines, deploy to Cloudflare or Hetzner. Early-stage setup.

Suggest a SaaS Tool

Missing a calculator or tool? Suggest what you'd like to see on our site.