yaiks / vue-cookie-comply

A Vue 3 compatible component to handle cookie consent
MIT License
69 stars 17 forks source link
consent cookies vue

:warning: Unmaintained repository

Hey everyone, hope you are doing well. I'm officially marking this repository as archived since from the beginning I wasn't able to give this project the love it deserved. All the code here is open source so feel free to fork and use it as you wish. Thanks for your understanding and see you around!

Vue Cookie Comply 🍪

A Vue 3 compatible component to handle cookie consent

Features

Heavily inspired by Airbnb's cookie consent UI

Demo

Check out a demo page using Vue 3, Vite and vue-cookie-comply: DEMO PAGE

Installation

This package is only compatible with Vue 3.x

First install vue-cookie-comply as a dependency of your Vue app:

yarn add vue-cookie-comply

# or

npm install vue-cookie-comply

Then, install vue-cookie-comply as a plugin wherever you create your Vue app:

import { createApp } from 'vue'
import App from './App.vue'
import VueCookieComply from 'vue-cookie-comply'
import 'vue-cookie-comply/dist/style.css'

const app = createApp(App)

app.use(VueCookieComply)
app.mount('#app')

Don't forget to import the css file if you want to leverage the default style 😉

Usage

Now you're ready to use the component <vue-cookie-comply /> it in your app:

<template>
  <main>
    <header />

    <div />

      <vue-cookie-comply
        :preferences="preferences"
        @on-accept-all-cookies="onAccept"
        @on-save-cookie-preferences="onSavePreferences"
      />

    <footer />
  </main>
</template>

vue-cookie-comply automatically places the component at the bottom of your page

Props

headerTitle

A string that goes into the component header. It defaults to "Cookie settings".

headerDescription

A string that gives more context to the user about your cookie policies. It defaults to the following text:

We use cookies and similar technologies to help personalize content and offer a better experience. You can opt to customize them by clicking the preferences button.

preferencesLabel

A string that controls the button label for the preferences button. It defaults to "Preferences".

acceptAllLabel

A string that controls the button label for the acceptance button. It defaults to "Accept All".

preferences

An array of objects to display the options of cookie preferences in the modal. The user may or may not be able to interact with a preference option (see isRequired field):

[
  {
    title: 'Performance',
    description:
      'Bla bla serviços que podemos oferecer erviços que podemos oferecer erviços que podemos oferecer erviços que podemos oferecer serviços que podemos oferecer.',
    items: [{ label: 'Active', value: 'performance', isRequired: true }],
  },
  {
    title: 'Analytics',
    description:
      'Bla bla serviços que podemos oferecer erviços que podemos oferecer erviços que podemos oferecer erviços que podemos oferecer serviços que podemos oferecer.',
    items: [
      { label: 'GoogleAnalytics', value: 'ga' },
      { label: 'Sentry', value: 'sentry', isEnable: true },
      { label: 'Mapbox', value: 'mapbox' },
      { label: 'New Relic', value: 'newRelic', isEnable: true },
      { label: 'Dog Food', value: 'dogfood' },
    ],
  },
];

Each object is a section of the preference's modal. Each section consists of the following values:

target

A string in form of a css selector to target where the preference modal will be placed in your app. It is used for the Teleport feature of Vue 3. It defaults to body, but you can attach any selector such as #app, .my-class, etc...

Events

on-accept-all-cookies

This event is dispatched when the user clicks the Accept All button. You can call your own handler to do whatever you might do in this case:

<template>
  <vue-cookie-comply
    :preferences="preferences"
    @on-accept-all-cookies="onAccept"
  />
</template>

<script>
  export default {
    methods: {
      onAccept() {
        console.log('User has accepted all cookies')
      }
    }
  }
</script>

After on-accept-all-cookies is dispatched, a item with key cookie-comply is placed in the localStorage, with the value all. You can use the presence of this key and value to do some logic on the client. Once the cookie-comply key exists in the localStorage, the vue-cookie-comply won't show anymore in the page.

on-save-cookie-preferences

This event is dispatched when the user open the modal and saves their preferences. The handler will receive an Array containing the values of preferences the user opted in:

<template>
  <vue-cookie-comply
    :preferences="preferences"
    @on-save-cookie-preferences="onSavePreferences"
  />
</template>

<script>
  export default {
    methods: {
      onSavePreferences(preferences) {
        console.log(preferences) // ['performance', 'ga', 'newRelic']
      }
    }
  }
</script>

After on-save-cookie-preferences is dispatched, a item with key cookie-comply is placed in the localStorage, with the value of an array containing the values the user opted in, eg. ['performance', 'ga', 'newRelic']. You can use the presence of this key and value to do some logic on the client. Once the cookie-comply key exists in the localStorage, the vue-cookie-comply won't show anymore in the page.

Composition

You can use slots to leverage composition and customize vue-cookie-comply with your own components. If the slots are not used, it will default to the internal components.

<vue-cookie-comply
  :preferences="preferences"
  @on-accept-all-cookies="onAcceptAll"
  @on-save-cookie-preferences="onSavePreferences"
>
    <template v-slot:header>
      <header>Custom header</header>
    </template>

    <template v-slot:modal-header>
      <h3>My custom modal header</h3>
    </template>

    <template v-slot:modal-body="{ preference, index }">
      <div>{{ preference.title }}</div>
    </template>

    <template v-slot:modal-footer>
      <footer>
        My custom modal footer
      </footer>
    </template>
  </vue-cookie-comply>

There are 4 slots to be customized: v-slot:header, v-slot:modal-header, v-slot:modal-body, v-slot:modal-footer.

Note that v-slot:modal-body is a scoped slot so you can have access to the preference's values 🤩.

Tricks

Since the modal it's using the Vue Teleport feature and it targets the <body> tag by default, if you have any global styles make sure they are applied to the body, so the modal can inherit styles such as font-family, color, etc..

body {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

Contributing

Feel free to open an issue with bugs, suggestions for features, enhancements, weird behaviours, questions and more. Also, feel more than welcome to open an PR to fix something you came across or improve the code 🚀