DEV Community

Cover image for gdpr-guard against GDPR-compliance's hassle

Posted on • Updated on


gdpr-guard against GDPR-compliance's hassle

Ladies and gentlemen, let me introduce to you: gdpr-guard.

Table Of Content

gdpr-guard logo

What is gdpr-guard?

gdpr-guard is a library that helps with the following tasks:

  • Describe the personal data processing in a tree-like structure
  • Make each feature or group of feature toggleable
  • Make a "cookie banner" workflow for
  • React to the user's choices when validated
  • Keep the data on the user's machine (or save it elsewhere if so desired)

What gdpr-guard does not help you with: build a uniform potentially themable UI. gdpr-guard is not a UI library, it provides the bare-bones logic and nothing else.

A tiny example

For this example, we'll use gdpr-guard as well as gdpr-guard-local.

First, we'll define our manager factory. We use a factory because we will restore the manager from local storage if it already exists.

import { GdprManagerBuilder, GdprStorage } from "gdpr-guard"

const managerFactory = () => 
    .startRequiredGroup(GdprStorage.Cookie, "Functionalities", "Information purely used to guarantee the proper behavior of the application")
      .withEnabledGuard("PHP_SESSID", "Server session identifier")
    .startGroup(GdprStorage.Cookie, "Analytics", "Tracking information used to better the UX")
      .withEnabledGuard("_ga", "Tracking identifier")
Enter fullscreen mode Exit fullscreen mode

Then we'll use the Savior API, which is used for handling saving and restoring the GDPR settings:

import { LocalStorageSavior, defaults } from "gdpr-guard-local"

const { makeConfig } = defaults;

const saviorConfig = {
  version: "v1.0.2", // Changing this, depending on your version comparison algorithm, will ask the user to configure their settings again
  storeKey: "gdprState", // The key used to save/restore the user's settings
  versionKey: "gdprVersion", // The key used to save/query the version of the savior the user saw last
  comparator: (lhs, rhs) => return lhs !== rhs, // How to detect if versions are different

const savior = new LocalStorageSavior(saviorConfig);
Enter fullscreen mode Exit fullscreen mode

For the sake of this example, we'll not use any of the bindings. It may seem a little too abstract, but bear with me. At this point you have both a factory and a savior which is all you need to use one.

Let's get our manager instance and listen to enabling/disabling events:

async function prepareGdprStuff() {
  // manager is an instance of GdprManager
  const manager = await savior.restoreOrCreate(managerFactory);"_ga", () => {
    // Load the GA scripts and execute stuff
  });"_ga", () => {
    // Disable GA if it's already loaded, for when users change their settings mid-execution

  if (manager.bannerWasShown) {

    Then we render stuff in the modal/banner, use listeners, query enabled state, etc...
Enter fullscreen mode Exit fullscreen mode

And just like that, with little to no effort, you can build a fully GDPR-compliant system with conditional script loading/execution.

The eco-system


Storage packages follow the following naming convention: gdpr-guard-<storage>. They almost always expose a class implementing the GdprSavior interface.

  • gdpr-guard-local to save the GDPR settings in local storage (by default, you can also provide your own store implementation)

Bindings / UI generation helpers

Binding packages follow the following naming convention: <binding>-gdpr-guard.

  • dom-gdpr-guard is the Vanilla JS binding that helps with rendering Elements for your GDPR settings UI
  • vue-gdpr-guard is the Vue 2 binding that provides a plugin and renderless components to help building your UI
  • react-gdpr-guard, the React hooks-based binding to help building your UI
  • vue3-gdpr-guard is the Vue 3 binding that provides composition API tools to help building your UI (WIP)
  • html-gdpr-guard is HTML / Vanilla JS binding that helps with building your GDPR manager from information already existing in the DOM

What do you think?

I'd love to hear what you think about it. Does it seem interesting compared to 3rd-party utilities that require back-and-forth with their servers or yours? Does it feel easy to use? What would you like to see? What would you like to change? Anything really.

Hope you at least enjoyed discovering it. I've been using it for at least 2 years on personal and professional projects. So far, it's been working great.

My two cents as the creator (and user)

Being able to fully detail every piece of data stored/grabbed is huge and not seen that often. The flexibility of choosing to have groups or not, groups within groups, etc... is pretty nice to have.

The fact that I designed the API to be mostly asynchronous also helps in situations where sessions are stored in your DB and you'd like to manage that here (e.g. if you conditionally render scripts).


My personal website (made with Nuxt) currently uses gdpr-guard, gdpr-guard-local and vue-gdpr-guard to handle its GDPR compliance.

You can have a look at:

  • The nuxt plugin code which defines savior and manager
  • The default layout which contains both the Banner Opener and the Banner itself as well as the code that handles clicking on the opener
  • The banner component which showcases how to handle persistence in different scenarios
  • The modal component which showcases how to display everything to the user so they can edit their preferences with the best granularity possible

Top comments (0)