0.0.8 • Published 2 years ago

@iammati/cookiebox v0.0.8

Weekly downloads
-
License
-
Repository
-
Last release
2 years ago

Version TypeScript support ES6 support

@iammati/cookiebox

Features

  • Resources won't load until you write a custom so-called Source
  • Simple and yet fast, colors of the cookiebox is customizable
  • Lightweight – Less than 2kb JavaScript and CSS!

Blocking resources is managed server-side – via PHP.

Why another cookie library?

To list exactly what the core issues were you may take a look at the following:

  • Static cached HTML files issue (see below for more)
  • Lightweight
  • RFC 6265 - HTTP State Management Mechanism compliant (thanks to js-cookie)
  • No jQuery
  • Modern compiler, optional TypeScript & ES6 support
  • Extending is super simple

Static cached HTML files issue

Imagine the following problem:

  • There are no caches on your web-server right now
  • Client performs a HTTP request to your server (opening example.org) - has no cookies yet
  • Server (depending on the CMS, framework etc.) builds an HTML and echo'd that output back to the client
  • Also the server: caches the HTML response thinking it's only static content, nothing special
  • Server doesn't know you serve iframes, scripts etc. which should be blocked since the user has not consent yet to get e.g. tracked, YouTube setting cookies etc.
  • All other clients who request example.org receive the wrong-cached static HTML file now

Solution:

  • Ship by default blocked third-party iframes/scripts etc. server-side
  • Unblock them only client-side via JavaScript

Installation

Install this package via npm i @iammati/cookiebox, yarn add @iammati/cookiebox or pnpm add @iammati/cookiebox.

Once installed, you can add it via an import statement as in:

import * as Cookiebox from '@iammati/cookiebox'
import YouTube from '@iammati/cookiebox/src/Sources/YouTube'
import GoogleMaps from '@iammati/cookiebox/src/Sources/GoogleMaps'

window.addEventListener('load', e => {
    Cookiebox.config(
        new YouTube(),
        new GoogleMaps(),
    ).init()
})

This will initialize the cookiebox with YouTube and GoogleMaps as so-called Sources.

What is a Source

Sources are e.g. YouTube, Google Maps, Google Analytics, Meta Pixel, Hotjar, Etracker, Matomo etc. So for each Source you need to write a corresponding Source-class, which could look like this:

export default class YouTube implements CookieSource {
    private iframes = document.getElementsByTagName('iframe');

    /**
     * The name of the cookie, which will also be saved inside the Cookie Storage of the browser.
     * Using kebabCase (see https://lodash.com/docs#kebabCase) is appropriate.
     */
    cookieName: string = 'youtube';

    /**
     * Callback function will be called, if the cookie with the name
     * of this class' cookieName property exists, it'll call this
     * function to handle the necessary logic.
     */
    cookieExist: Function = () => {
        for (const iframe of this.iframes) {
            const src = iframe.hasAttribute('src') ? iframe.getAttribute('src') : iframe.getAttribute('data-src');

            if (!src.includes('youtube.com/')) {
                continue;
            }

            !iframe.hasAttribute('src') && iframe.setAttribute('src', src);
            iframe.removeAttribute('data-src');
            !iframe.parentElement.classList.contains('allowed') &&
                iframe.parentElement.classList.add('allowed')
            ;
        }
    };

    /**
     * Callback function will be called if the cookie
     * does not exist inside the Cookie Storage of the browser aka.
     * the client has not yet accept that cookie.
     */
    cookieDoesNotExist: Function = () => {
        for (const iframe of this.iframes) {
            const src = iframe.hasAttribute('src') ? iframe.getAttribute('src') : iframe.getAttribute('data-src');
            if (!src.includes('youtube.com/')) {
                continue;
            }

            iframe.hasAttribute('src') && iframe.removeAttribute('src');
            iframe.setAttribute('data-src', src);
            iframe.parentElement.classList.contains('allowed') &&
                iframe.parentElement.classList.remove('allowed')
            ;
        }
    };
}

Adding your own Source

Depending on your compiler (you should be more than enough covered using webpack/vite) all you have to do is to create a new JavaScript class and instancing it inside the Cookiebox.config function, just like YouTube and GoogleMaps have been done.

export default class Test implements CookieSource {
    cookieName: string = 'test';

    cookieExist: Function = () => {
        console.log('My awesome test source cookieExist function has beel called!');
    };

    cookieDoesNotExist: Function = () => {
        console.warn('My awesome test source cookieDoesNotExist function has beel called!');
    };
}

Note: You can choice by yourself using TypeScript or JavaScript.

In case you project is not using TypeScript at all, simply remove the type-hints and the implementation of the CookieSource interface:

export default class Test {
    cookieName = 'test';

    cookieExist = () => {
        console.log('My awesome test source cookieExist function has beel called!');
    };

    cookieDoesNotExist = () => {
        console.warn('My awesome test source cookieDoesNotExist function has beel called!');
    };
}

Heading back to your main entrypoint of your project's JavaScript code (assuming it's called index.js):

window.addEventListener('load', e => {
    Cookiebox.config(
        new YouTube(),
        new GoogleMaps(),
        new Test()
    ).init()
})

As you may noticed, you simply add just another class and you are good to go.

Concepts

  • Blocking third-party iframes/scripts is managed via PHP
  • The cookie is set to a duration of 365 days
  • Focus is the european GDPR

TODOs / Proofments

  • Coverage of US cookie consent law (since there's no GDPR law atm?)

Credits

This package was created by myself, for myself (and educational purpose). Thanks, Mati

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago