[01] OpenCookies

@opencookies/vue

Vue 3 adapter — plugin or provider with composables and ConsentGate

Vue 3 adapter for OpenCookies. Bridges @opencookies/core with Vue's reactivity via shallowRef and computed.

Install#

bun add @opencookies/core @opencookies/vue

Peer dependencies: vue >= 3.4.

Setup#

Register the plugin once on your app:

import { createApp } from "vue";
import { OpenCookiesPlugin } from "@opencookies/vue";
import App from "./App.vue";

createApp(App)
  .use(OpenCookiesPlugin, {
    config: {
      categories: [
        { key: "essential", label: "Essential", locked: true },
        { key: "analytics", label: "Analytics" },
        { key: "marketing", label: "Marketing" },
      ],
    },
  })
  .mount("#app");

Or scope a store to a subtree with the <OpenCookiesProvider> component:

<script setup lang="ts">
import { OpenCookiesProvider } from "@opencookies/vue";
</script>

<template>
  <OpenCookiesProvider :config="{ categories }">
    <App />
  </OpenCookiesProvider>
</template>

You can pass a pre-created store to either entry point with { store } instead of { config }.

API#

useConsent()#

Returns reactive refs for the current consent state plus action methods. Use it inside setup() or any <script setup> block.

<script setup lang="ts">
import { useConsent } from "@opencookies/vue";

const { route, decisions, acceptAll, acceptNecessary, setRoute } = useConsent();
</script>

<template>
  <div v-if="route === 'cookie'">
    <button @click="acceptNecessary">Necessary only</button>
    <button @click="acceptAll">Accept all</button>
    <button @click="setRoute('preferences')">Customize</button>
  </div>
</template>

useCategory(key)#

Granular per-category access. Returns a granted computed and a toggle action.

<script setup lang="ts">
import { useCategory } from "@opencookies/vue";

const { granted, toggle } = useCategory("analytics");
</script>

<template>
  <label>
    <input type="checkbox" :checked="granted" @change="toggle" />
    Analytics
  </label>
</template>

<ConsentGate>#

Renders the default slot when an expression is satisfied, optionally a fallback slot otherwise. The component itself emits no DOM wrapper.

<script setup lang="ts">
import { ConsentGate } from "@opencookies/vue";
import Chart from "./Chart.vue";
import EnablePrompt from "./EnablePrompt.vue";
</script>

<template>
  <ConsentGate requires="analytics">
    <Chart />
    <template #fallback>
      <EnablePrompt />
    </template>
  </ConsentGate>

  <ConsentGate :requires="{ and: ['analytics', 'marketing'] }">
    <PersonalizedPromo />
  </ConsentGate>
</template>

Options API#

The composables are usable from Options API via setup():

<script lang="ts">
import { defineComponent } from "vue";
import { useConsent, useCategory } from "@opencookies/vue";

export default defineComponent({
  setup() {
    const consent = useConsent();
    const analytics = useCategory("analytics");
    return { consent, analytics };
  },
});
</script>

<template>
  <button @click="consent.acceptAll()">Accept all</button>
  <input type="checkbox" :checked="analytics.granted" @change="analytics.toggle()" />
</template>

Nuxt 3#

Register the plugin in a Nuxt plugin file:

// plugins/opencookies.ts
import { OpenCookiesPlugin } from "@opencookies/vue";
import type { Category } from "@opencookies/core";

const categories: Category[] = [
  { key: "essential", label: "Essential", locked: true },
  { key: "analytics", label: "Analytics" },
];

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(OpenCookiesPlugin, { config: { categories } });
});

Shared concepts#

Categories, GPC handling, jurisdiction resolvers, re-consent triggers, script gating (gateScript), and storage adapters all live in @opencookies/core — the Vue adapter is a thin reactivity wrapper. A working example is in examples/vue.

See also#

License#

Apache-2.0