Orejime Consent Manager

repository·main·Indexed 41 days ago

https://github.com/boscop-fr/orejime

A lightweight and accessibility-focused consent manager (v3.2.1) that allows website users to manage cookie preferences. It features a configuration-driven approach via window.orejimeConfig, supports standalone bundles for themes and languages, and uses <template> tags to manage third-party scripts. Includes a core manager for tracking consent states, event subscriptions for updates, and specialized themes including a DSFR theme for the French government's design system.

Tokens
10.3K
Snippets
39
Records
45
Agent score
50%

What's inside Orejime

  1. Use contextual consent for embedded content

    main

    For content like YouTube iframes that are restricted by consent, use the data-contextual attribute on the <template> tag. This displays a fallback notice with a reason and a way to consent in place, rather than showing nothing.

    You can also customize the heading level of the notice's title using the data-title-level attribute on the template.

    <!-- Contextual notice for YouTube -->
    <template data-purpose="youtube" data-contextual data-title-level="6">
      <iframe src="https://www.youtube.com/embed/toto"></iframe>
    </template>
  2. Configure third-party scripts with <template> tags

    main

    To prevent scripts from executing before user consent, wrap them in a <template> tag with a data-purpose attribute matching an id defined in your purposes configuration. Orejime will automatically load these elements once the corresponding consent is granted.

    You can wrap single scripts or multiple elements (like <iframe> or multiple <script> tags) within a single template.

    <!-- Single script -->
    <template data-purpose="google-tag-manager">
      <script>
        (function(w,d,s,l,i){/* ... */})(window,document,'script','dataLayer','GTM-XXXX')
      </script>
    </template>
    
    <!-- Multiple elements -->
    <template data-purpose="ads">
      <script src="https://annoying-ads.net"></script>
      <iframe src="https://streaming.ads-24-7.com/orejime"></iframe>
    </template>
  3. Install Orejime via CDN or npm

    main

    Orejime is distributed as individual modules following the convention orejime-[THEME]-[LANGUAGE].

    CDN Method

    The easiest way is to import a distribution via jsDelivr. It is recommended to use a fixed version instead of @latest to avoid breaking changes.

    npm Method

    Orejime distributes built files via npm. After installation, you can find the required JS and CSS files in the dist folder.

    Note: As of version 3, Orejime provides standalone builds only and cannot be bundled as a standard module.

    <!-- CDN Example -->
    <script src="https://cdn.jsdelivr.net/npm/orejime@3.0.0/dist/orejime-standard-en.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/orejime@3.0.0/dist/orejime-standard.css" rel="stylesheet" />
    npm install orejime
  4. Customize Orejime themes

    main

    Standard Theme

    The standard theme can be customized using CSS variables on the .orejime-Env class.

    DSFR Theme

    The DSFR theme is designed for the French government's design system. It does not provide its own styles but uses the correct markup and class names to integrate with existing DSFR styles.

    /* Customizing the Standard Theme */
    .orejime-Env {
      --orejime-font-family: monospace;
      --orejime-color-background: black;
      --orejime-color-text: yellow;
    }
  5. Use standalone Orejime bundles for specific themes and languages

    main

    Instead of loading multiple chunks for the core, UI, and language files, you can use standalone packages that bundle everything together. This approach is more optimized for websites using a single theme and a single language, as it reduces network requests and allows for better compression.

    Each standalone package provides a specific combination of a theme and a language. For example, if you want to use the DSFR theme with English translations, you would install and use the orejime-dsfr-en package.

  6. Set up a local development environment

    main

    To contribute to Orejime or create a custom build, follow these steps:

    1. Clone the repository.
    2. Install dependencies: npm install.
    3. Start the development server: npm run serve.
    4. Access the demo at http://localhost:3000. The page will automatically reload on JS or CSS changes.
    npm install
    npm run serve
  7. Migrate from Version 2 to Version 3

    main

    Version 3 introduced a major overhaul of the configuration to align with GDPR vocabulary.

    Configuration Changes: If you are upgrading from version 2, use the migration tool at https://orejime.boscop.fr/#migration to update your configuration object.

    Third-party Scripts Changes: In version 3, you no longer need to modify third-party <script> tags with custom attributes. Instead, leave the scripts untouched and wrap them in a <template> tag with a data-purpose attribute.

  8. Configure cookie associations for a Purpose

    main

    When defining a Purpose, you must specify which cookies it covers using the PurposeCookie type. A cookie can be identified in three ways:

    1. A string: The exact name of the cookie.
    2. A RegExp: A regular expression to match cookie names.
    3. PurposeCookieProps: A tuple [pattern: RegExp, path: string, domain: string] for precise matching including path and domain constraints.
    export type PurposeCookie = string | RegExp | PurposeCookieProps;
    
    // Example usage:
    const analyticsPurpose: Purpose = {
      id: 'analytics',
      cookies: [
        'ga_session',
        /^_ga/, // Matches any cookie starting with _ga
        [/^analytics_/, '/app', 'example.com'] // Precise tuple matching
      ]
    };
  9. Define purposes and purpose groups

    main

    Orejime uses a hierarchical structure to organize cookie purposes. You can provide a PurposeList, which is an array containing either Purpose objects or PurposeGroup objects.

    • Purpose: Represents a specific cookie usage category. It extends the core Purpose type and adds a UI-specific id, title, and optional description.
    • PurposeGroup: A container for multiple Purpose objects, allowing you to group related categories under a single id, title, and optional description.
    // Example of a PurposeList structure
    const purposes: PurposeList = [
      {
        id: 'group-1',
        title: 'Marketing',
        purposes: [
          { id: 'ad-tracking', title: 'Ad Tracking', description: 'Used for ads' }
        ]
      },
      {
        id: 'essential',
        title: 'Essential Cookies'
      }
    ];
  10. Understand the ConsentsMap structure

    main

    A ConsentsMap is a dictionary representing the current consent state for all defined purposes. The keys are the ids of the Purpose objects, and the values are booleans indicating whether consent has been granted (true) or denied (false).

    export type ConsentsMap = {[id: Purpose['id']]: boolean};
    
    // Example:
    const currentConsents: ConsentsMap = {
      'analytics': true,
      'marketing': false,
      'essential': true
    };
  11. Configure Orejime via window.orejimeConfig

    main

    Orejime requires configuration to function. This is typically done by assigning an object to window.orejimeConfig before initialization.

    Required options:

    • privacyPolicyUrl: A link to your privacy policy page (required for GDPR compliance).
    • purposes: An array of third-party purposes to manage.

    Purpose Object Schema:

    • id (string): Internal identifier.
    • title (string): Display name in the banner/modal.
    • description (string, optional): Detailed description.
    • cookies (array, optional): A list of regex expressions, strings, or arrays [name, path, domain] representing cookies to be deleted if consent is withdrawn.
    • isMandatory (boolean, default: false): If true, the user cannot disable this purpose.
    • isExempt (boolean, default: false): If true, the purpose loads even before explicit consent.
    • default (boolean, default: false): If true, the purpose is enabled by default.
    • runsOnce (boolean, default: false): If true, the purpose executes only once regardless of toggling.
    • purposes (array, optional): Allows grouping sub-purposes under a parent purpose.
    window.orejimeConfig = {
      privacyPolicyUrl: 'https://example.com/privacy',
      purposes: [
        {
          id: 'google-tag-manager',
          title: 'Google Tag Manager',
          description: 'Used for analytics.',
          cookies: ['_ga', '/^_gat_.+$/i'],
          isMandatory: false
        },
        {
          id: 'advertising',
          title: 'Advertising',
          purposes: [
            { id: 'foo', title: 'Foo', cookies: [] }
          ]
        }
      ],
      forceModal: false,
      forceBanner: false,
      logo: '/img/logo.png',
      orejimeElement: '#orejime',
      cookie: {
        name: 'orejime',
        duration: 365,
        domain: 'mydomain.com',
        sameSite: 'strict'
      }
    };
  12. Initialize Orejime via UMD (Script Tags)

    main

    When using Orejime via a <script> tag (UMD), you can configure the library by defining a global orejimeConfig object on the window before the script loads.

    Once initialized, the library exposes three global properties on the window object:

    1. orejimeConfig: The configuration object used for initialization.
    2. orejime: The initialized OrejimeInstance.
    3. loadOrejime: A function to manually trigger initialization with a specific configuration.

    To detect when Orejime has finished loading and is ready for use, listen for the orejime.loaded event on the document object. The event's detail property contains the OrejimeInstance.

    <!-- 1. Define configuration -->
    <script>
      window.orejimeConfig = {
        // your config here
      };
    </script>
    
    <!-- 2. Load Orejime script -->
    <script src="path/to/orejime.umd.js"></script>
    
    <!-- 3. Listen for initialization -->
    <script>
      document.addEventListener('orejime.loaded', (event) => {
        const orejime = event.detail;
        console.log('Orejime is ready:', orejime);
      });
    </script>