Nuxt Cookie Control

repository·main·Indexed 43 days ago

https://github.com/dargmuesli/nuxt-cookie-control

A Nuxt module for managing user cookie consent in compliance with GDPR. It provides a customizable UI banner and modal for accepting or declining cookie categories, a `useCookieControl()` composable for tracking consent state, and a programmatic API via `@dargmuesli/nuxt-cookie-control/kit` for registering cookies during the module setup phase.

Tokens
4.7K
Snippets
19
Records
21
Agent score
55%

What's inside Nuxt Cookie Control

  1. Configure Nuxt Cookie Control module options

    main

    You can configure the module in your nuxt.config.js using either the cookieControl key or by passing options directly to the module array.

    Available configuration keys include:

    • barPosition: Position of the cookie bar ('top-left', 'top-right', 'top-full', 'bottom-left', 'bottom-right', 'bottom-full').
    • colors: Object containing various UI color overrides.
    • cookies: Object defining necessary and optional cookies.
    • cookieExpiryOffsetMs: Expiry offset in milliseconds.
    • cookieNameIsConsentGiven: Name of the consent cookie (default: 'ncc_c').
    • cookieNameCookiesEnabledIds: Name of the enabled IDs cookie (default: 'ncc_e').
    • isModalForced: If true, the modal is shown immediately.
    • locales: Array of supported locales (e.g., ['en']).
    • localeTexts: Object to override specific translations per locale.
    // nuxt.config.js
    
    modules: [
      '@dargmuesli/nuxt-cookie-control'
    ],
    cookieControl: {
      // typed module options
    }
    
    // or
    
    modules: [
      ['@dargmuesli/nuxt-cookie-control', {
        // untyped module options
      }]
    ]
  2. Programmatically register cookies via Kit

    main

    Other Nuxt modules can register cookies during their setup phase using the @dargmuesli/nuxt-cookie-control/kit export. This is intended for use within the setup() phase of a Nuxt module.

    addCookieControl(cookie, type, nuxt?):

    • cookie: The Cookie object to register.
    • type: The CookieType (CookieType.NECESSARY or CookieType.OPTIONAL).
    • nuxt: (Optional) The Nuxt instance.

    Note: This must be called during the module setup phase, not at runtime.

    // modules/my-analytics-module.ts
    
    import { defineNuxtModule } from '@nuxt/kit'
    import { addCookieControl, CookieType } from '@dargmuesli/nuxt-cookie-control/kit'
    
    export default defineNuxtModule({
      setup() {
        addCookieControl(
          {
            id: 'google-analytics',
            name: 'Google Analytics',
            description: 'Tracks user interactions and page views.',
            src: 'https://www.googletagmanager.com/gtag/js',
          },
          CookieType.OPTIONAL
        )
      }
    })
  3. Use the useCookieControl composable

    main

    The useCookieControl() composable provides access to the current state of cookie consent. Use it to react to changes in user consent or to conditionally initialize third-party scripts.

    Returned properties:

    • cookiesEnabled: Boolean indicating if any cookies are enabled.
    • cookiesEnabledIds: Array of IDs of currently enabled cookies.
    • isConsentGiven: Boolean indicating if the user has provided consent.
    • isModalActive: Boolean indicating if the configuration modal is open.
    • moduleOptions: The module's configuration object.
    <!-- app.vue -->
    
    <template>
      <CookieControl locale="en" />
    </template>
    
    <script setup lang="ts">
    const {
      cookiesEnabled,
      cookiesEnabledIds,
      isConsentGiven,
      isModalActive,
      moduleOptions,
    } = useCookieControl()
    
    // example: react to a cookie being accepted
    watch(
      () => cookiesEnabledIds.value,
      (current, previous) => {
        if (
          !previous?.includes('google-analytics') &&
          current?.includes('google-analytics')
        ) {
          // cookie with id `google-analytics` got added
          window.location.reload()
        }
      },
      { deep: true },
    )
    </script>
  4. Customize CookieControl with component slots

    main

    The <CookieControl> component provides several slots to customize the appearance of the bar, the modal, and individual cookie items.

    Available slots:

    • #bar: Customize the cookie bar content.
    • #modal: Customize the configuration modal content.
    • #cookie: Customize how individual cookies are rendered. Receives a { cookie } object.

    Additionally, <CookieIframe> provides:

    • #iframe: Content to show when iframes are blocked.
    • #controlButton: Custom control button content.
    <!-- Customizing the Cookie list -->
    <CookieControl>
      <template #cookie="{ cookie }">
        <h3 v-text="cookie.name" />
        <span v-html="cookie.description" />
    
        <div v-if="cookie.targetCookieIds">
          <b>Cookie ids: </b>
          <span v-text="cookie?.targetCookieIds?.join(', ')" />
        </div>
      </template>
    </CookieControl>
  5. Configure ModuleOptions for Nuxt Cookie Control

    main

    The ModuleOptions interface defines the configuration schema for the Nuxt Cookie Control module. You can use these options in your nuxt.config.ts to control the appearance, behavior, and cookie definitions of the consent banner and modal.

    Key Configuration Groups

    • Cookie Definitions: Define your cookies under cookies.necessary and cookies.optional using the Cookie interface.
    • Appearance: Control the banner position via barPosition (e.g., 'top-left', 'bottom-full') and customize colors via the colors object.
    • Localization: Specify supported languages in locales and provide translations in localeTexts using the LocaleStrings structure.
    • Behavior: Toggle features like isModalForced, isControlButtonEnabled, or declineAllAcceptsNecessary to change how users interact with the consent UI.
    export interface ModuleOptions {
      barPosition: 'top-left' | 'top-right' | 'top-full' | 'bottom-left' | 'bottom-right' | 'bottom-full'
      closeModalOnClickOutside: boolean
      colors: false | Record<string, unknown>
      cookieExpiryOffsetMs: number
      cookieNameCookiesEnabledIds: string
      cookieNameIsConsentGiven: string
      cookies: {
        necessary: Cookie[]
        optional: Cookie[]
      }
      cookieOptions: CookieOptions & { readonly?: false }
      isAcceptNecessaryButtonEnabled: boolean
      isControlButtonEnabled: boolean
      isCookieIdVisible: boolean
      isCssEnabled: boolean
      isCssPonyfillEnabled: boolean
      isDashInDescriptionEnabled: boolean
      isIframeBlocked: boolean
      isModalForced: boolean
      declineAllAcceptsNecessary: boolean
      locales: Locale[]
      localeTexts: PartialRecord<Locale, Partial<LocaleStrings>>
    }
  6. Configure cookie objects

    main

    Cookies defined in the cookies configuration object require specific properties. Note that isPreselected: true is allowed for UI purposes but does not enable the cookie (to remain GDPR compliant). Properties like description and name can be translatable objects.

    {
      description: {
        en: 'This cookie stores preferences.'
      },
      id: 'p',
      isPreselected: false,
      name: {
        en: 'Preferences'
      },
      links: {
        'https://example.com/privacy': 'Privacy Policy',
        'https://example.com/terms': 'Terms of Service',
      },
      src: 'https://example.com/preferences/js?id=<API-KEY>',
      targetCookieIds: ['xmpl_a', 'xmpl_b'],
    }
  7. Define a Cookie

    main

    When configuring the module, each cookie must follow the Cookie interface. This allows you to describe the cookie's purpose and how it should be presented to the user.

    • id: A unique identifier for the cookie.
    • name: The display name (can be a string or a translatable object).
    • description: A description of what the cookie does (can be a string or a translatable object).
    • isPreselected: If true, the cookie is enabled by default in the settings.
    • targetCookieIds: An array of other cookie IDs that this cookie depends on.
    • links: A record of links related to the cookie (e.g., privacy policy).
    export interface Cookie {
      description?: Translatable
      id: string
      isPreselected?: boolean
      name: Translatable
      links?: Record<string, string | null>
      src?: string
      targetCookieIds?: string[]
    }
  8. Resolve translatable cookie content

    main

    The resolveTranslatable function is used to extract a string from a Translatable object based on a provided locale. If the input is already a string, it is returned as-is. If it is an object, the function looks up the key corresponding to the locale.

    Note that if a locale is provided but the corresponding key is missing in the Translatable object, it will throw an error. If the input is an object and no locale is provided, it will also throw an error.

    Available locales default to LOCALE_DEFAULT if not specified.

    // If translatable is a string, it returns the string
    resolveTranslatable('Hello') // returns 'Hello'
    
    // If translatable is an object, it returns the value for the locale
    const translations = { en: 'Hello', fr: 'Bonjour' }
    resolveTranslatable(translations, 'fr') // returns 'Bonjour'
  9. Access Cookie Control state via $cookies

    main

    The module injects a $cookies object into the Nuxt application and Vue components. This object provides reactive access to the current consent state.

    Available properties in $cookies (type State):

    • cookiesEnabled: A Ref containing the list of currently enabled Cookie objects.
    • cookiesEnabledIds: A Ref containing an array of IDs for the enabled cookies.
    • isConsentGiven: A Ref<boolean> indicating if the user has provided consent.
    • isModalActive: A Ref<boolean> indicating if the settings modal is currently open.
    • locale: A Ref<Locale> representing the current language.
    • moduleOptions: The configuration options used by the module.
    declare module '#app' {
      interface NuxtApp {
        $cookies: State
      }
    }
    
    declare module 'vue' {
      interface ComponentCustomProperties {
        $cookies: State
      }
    }
  10. Use the useResolveTranslatable hook for translations

    main

    The useResolveTranslatable function is a factory that returns a specialized translation function bound to a specific locale. This is useful for creating a reusable resolver that automatically uses the current application locale without needing to pass it manually every time.

    It uses LOCALE_DEFAULT as the fallback locale if none is provided to the factory.

    // Create a resolver for a specific locale
    const resolve = useResolveTranslatable('en')
    
    // Use the resolver on translatable data
    const text = resolve({ en: 'Hello', es: 'Hola' }) // returns 'Hello'