Simple Cookie Notice

js/cookie-consent.js

v3.0.0 Stable (breaking: `rd-js-` hook) | CDN (minified) | Download download

A lightweight, dependency-free cookie notice banner written in plain HTML and JavaScript.

This snippet displays a basic notification informing users that the website uses cookies and hides it after user acknowledgment by storing a browser cookie.

It is designed to be simple, transparent, and easy to integrate into static websites, including Eleventy (11ty).

Cookies consent script example

Important Legal Disclaimer ⚠️

This project is NOT a full cookie consent management solution.

It does not:

  • Implement granular consent (analytics / marketing / necessary cookies)
  • Block scripts prior to consent
  • Provide region-specific compliance logic
  • Guarantee compliance with GDPR, ePrivacy Directive, CCPA, CPRA, or any other local or international privacy regulations

Its sole purpose is to inform users that cookies are used and to remember that the notice has been dismissed. This project provides notification, not legal compliance. Use at your own risk.

If your website is subject to specific legal requirements, consult a qualified legal professional and consider using a dedicated Consent Management Platform (CMP).

Features

  • No dependencies
  • No build step
  • Plain JavaScript (ES5+)
  • Stores dismissal state in a browser cookie
  • Works on static websites
  • Safe cookie defaults (SameSite=Lax, Secure on HTTPS)

How It Works

  1. On page load, the script checks for a cookie named cookie-notice-dismissed
  2. If the cookie is present, the notice is hidden by adding the rd-is-hidden state class
  3. When the user clicks the confirmation button, the cookie is set and the notice gets rd-is-hidden
  4. The notice stays hidden for subsequent visits

Default cookie lifetime: 31 days

Installation

⚠️ Performance tip: For production, download the script and host it on your own server rather than loading it from a CDN.

Required HTML Markup

The script expects the following mandatory hook classes. If they are missing or renamed, the script safely does nothing.

<div class="cookie-notice rd-js-cookie-consent">
  <div class="cookie-notice__content">
    <h3>🍪</h3>
    <p class="bold">Help yourself to some cookies!</p>
    <p>We’re using third party cookies and scripts to improve the functionality of this website. For legal purpose, we have a <a href="/legal/privacy">Privacy Policy</a>.</p>
    <div class="right">
      <button class="cookie-notice__button rd-js-cookie-accept">Nice!</button>
    </div>
  </div>
</div>
Required hooks (Mandatory)

Be sure to include the mandatory hook classes on your HTML elements:

Hook class Purpose
rd-js-cookie-consent Root container the script hides by toggling rd-is-hidden
rd-js-cookie-accept Button (inside the container) that dismisses the notice

Hook classes are read by the JavaScript and never styled — presentational styling belongs to separate classes (cookie-notice, cookie-notice__button) which you are free to rename or replace.

Required CSS (Minimum)

The Rare Styles Library already includes styles for the cookie consent block (including the rd-is-hidden state). If you use this script on its own, make sure to add the required styles. At minimum, the .rd-is-hidden { display: none; } rule must exist — the script hides the notice by toggling that class, never by inline styles.

.cookie-notice {
    max-width: var(--site-max-width);
    display: block;
    position: fixed; 
    bottom: 10px; 
    left: 50%;
    transform: translateX(-50%);
    background: #f0f0f0;
    color: #000;
    padding: var(--space-lg) var(--space-lg) var(--space-md);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
    border-radius: 15px;
    box-sizing: border-box;
    z-index: 1000;

    @include bp.mobile {
        padding: 15px 5%;
        width: 90%;
    }
}

.cookie-notice__content {
    position: relative;
}

.cookie-notice__content h3 {
    position: absolute;
    margin: 0;
    top: -50px;
    font-size: 3.5em;

    @include bp.mobile {
        font-size: 2.5em;
        top: -60px;
    }
}

.cookie-notice__content a {
    color: #000;
    text-decoration: none;
    border-bottom: 1px solid var(--brand-color);
}

.cookie-notice__content button {
    position: relative;
    display: inline-block;
    margin-top: var(--space-md);
}

/* State class the script toggles — mandatory */
.rd-is-hidden {
    display: none;
}

You are free to fully replace these styles with your own design system.

JavaScript Setup

Include the script synchronously, right after the notice markup (no defer, no async):

<script src="/assets/js/cookie-consent.js"></script>

Placement matters: the script initializes immediately when the notice markup is already parsed, so the dismissal check runs before the browser paints the content that follows — a returning visitor never sees the notice flash. If the markup is not there yet, the script falls back to DOMContentLoaded. No configuration is required.

Optional anti-flash guard. If you load the script with defer/async or from a CDN late in the page, the paint-then-hide flash comes back for returning visitors. In that case add this one-liner right after the notice markup:

<script>
if (document.cookie.indexOf('cookie-notice-dismissed=true') !== -1) {
document.querySelector('.rd-js-cookie-consent').classList.add('rd-is-hidden');
}
</script>

Assumptions Made by the Script

  • JavaScript is enabled
  • Cookies are enabled
  • The site operates on a single domain
  • The notice markup exists on the page where the script runs

If any of these assumptions are false, the script will fail silently.

Customization

You may safely change:

  • Text content
  • Styles and class names
  • Cookie lifetime (in days)
  • Cookie name

The rd-js-cookie-consent / rd-js-cookie-accept hook classes and the rd-is-hidden state class are the script’s contract — if you rename them, you must update the script accordingly.

Changelog

v3.0.0

  • Breaking: hooks moved to the rd-js contract — the script finds elements via the rd-js-cookie-consent / rd-js-cookie-accept classes; the cookie-notice / cookie-notice-accept IDs are no longer read
  • Breaking: visibility is expressed by the rd-is-hidden state class instead of inline style.display
  • Anti-FOUC: the script no longer waits for DOMContentLoaded when the notice markup is already parsed — included synchronously after the markup, it hides a dismissed notice before paint; an optional inline guard is documented for defer/CDN setups
  • Added a guard: pages without the markup no longer run the listeners