Consent Docs

Cookies and browser storage

The cookies and local storage keys the browser runtime writes, their formats and lifetimes, and the functions that parse them.

Reference4 min readFor developers using the browser runtime and the server and mobile SDKs

The browser runtime keeps the visitor's choice in first-party cookies and in local storage. Their names, formats and lifetimes are listed here, with the functions that parse the cookies.

Requirements#

  • Runtime version 1.0.7, loaded with a publishable key.
  • To parse the cookies in a bundle: the @piedap/consent npm package.
  • To parse them on a server: the Node.js helpers or the Python helpers.

Install#

Load the runtime with the script tag or the npm package. See Browser runtime options.

Import the parsers#

JavaScript
import {
  parseConsentCookie,
  parsePartnerCookie,
  COOKIE_NAME,
  PARTNER_COOKIE_NAME,
} from '@piedap/consent';

COOKIE_NAME is piedap_consent and PARTNER_COOKIE_NAME is piedap_partners.

Cookies#

Cookie Written Holds
piedap_consent At every choice Which purposes are allowed.
piedap_partners Only while some partners of an allowed purpose are switched off The partners that are off.
euconsent-v2 Where IAB TCF applies The TC string.

Each cookie is set with these attributes:

Attribute Value
Path /
SameSite Lax
Secure Set on HTTPS pages.
Domain Set only when cookieDomain or data-piedap-cookie-domain is given.
Max-Age The form's consent period, and never more than 395 days.

Lets your server read the choice on the next request.

1|<consent id>|<form version>|<purposes>|<decided at>
Part Value
1 The format version.
Consent id The record's id, or pending until the API has stored the answer.
Form version The version of the form that was answered.
Purposes key:1 for allowed and key:0 for refused, sorted by key and joined with ~.
Decided at Unix time in seconds.
1|cns_3f9a1c0e5b7d4a2c9e8f6b1d0a7c5e42|3|analytics:1~marketing:0|1790577672

The value is percent-encoded in the cookie itself, so document.cookie shows 1%7Ccns_…%7C3%7C…. Decode it before you split it.

piedap_partners#

Lists the partners that are off under a purpose the visitor allowed.

1|<purpose>:<partner>.<partner>~<purpose>:<partner>
Part Value
1 The format version.
Purpose A purpose key. Purposes are joined with ~.
Partner A partner key that is off. Partner keys are joined with ..
1|analytics:matomo.plausible~marketing:meta

A partner that is not listed follows its purpose in piedap_consent. The cookie is removed when no partner is off.

euconsent-v2#

Holds the IAB TC string where IAB TCF applies. See IAB TCF and GPP.

Parse the cookies#

parseConsentCookie()#

Reads a piedap_consent value.

Parameter Type Required or default Description
value string | null | undefined Required The cookie value, raw or percent-encoded.

Returns { consentId, formVersion, decisions, decidedAt }, or null. consentId is null while the cookie says pending. decisions maps a purpose key to allowed, and decidedAt is a Date.

Errors None. A missing or malformed cookie returns null.

JavaScript
function cookie(name) {
  const match = document.cookie
    .split('; ')
    .find((part) => part.startsWith(`${name}=`));
  return match ? match.slice(name.length + 1) : null;
}

const consent = parseConsentCookie(cookie(COOKIE_NAME));
console.log(consent?.decisions.analytics); // true

parsePartnerCookie()#

Reads a piedap_partners value.

Parameter Type Required or default Description
value string | null | undefined Required The cookie value, raw or percent-encoded.

Returns Record<string, string[]>, purpose key to the partner keys that are off, or null.

Errors None. A missing or malformed cookie returns null.

JavaScript
const declined = parsePartnerCookie(cookie(PARTNER_COOKIE_NAME));
console.log(declined); // { analytics: ['matomo', 'plausible'] }

The cookie is the browser's own copy

A visitor can edit a cookie. Use it to decide what to load. For a decision that must be authoritative, read the record from the API with a secret key.

Local storage#

Key Holds
piedap.consent.v2 The full state as JSON. See the fields below.
piedap.consent.frameworks { "tcf": boolean, "gpp": boolean }: whether the last form used an IAB framework, so the next page can install the stubs at once.
piedap.consent.discovery The time of this browser's last cookie discovery report, sent at most once a day.

piedap.consent.v2 has these fields:

Field Holds
version The format of the entry, 2.
subjectId The browser's random id.
forms One entry per form answered: its purposes, partners, categories, consent id and expiry.
current The form answered last.
pending Answers and withdrawals still waiting to reach the API, oldest first.
noticeDismissed Notices the visitor has dismissed.
locale The language the visitor chose.
eighteenOrOver The visitor's answer to "Are you 18 or older?", once given.

Each answer and each withdrawal goes into pending before its request is sent, together with the request itself. It leaves pending when the API has it. A request cut off by the visitor leaving the page is sent again on the next page. It goes with the same body and the same Idempotency-Key, so the API records it once.

Writes for one form are sent one after another, in the order they were made. A write that fails 8 times is dropped.

If local storage is not available, the runtime keeps the state in memory for the page view and relies on the cookie. On a subdomain that shares the cookie but not the storage, it sends the cookie's consent id to the API and adopts the recorded answer.

Cookies removed on refusal#

When a category stops being allowed, the runtime deletes the first-party cookies known to belong to it. The list is your project's cookie declaration plus these names:

Category Cookie names
ANALYTICS _ga, _ga_<id>, _gid, _gat, _gat_…, _hj…, _clck, _clsk, mp_…_mixpanel, amp_…, _pk_id.…, _pk_ses.…, ajs_user_id, ajs_anonymous_id, ph_…_posthog
MARKETING _gcl_au, _gcl_aw, _gcl_dc, _gcl_gb, _gcl_gf, _gcl_ha, _fbp, _fbc, _uetsid, _uetvid, _ttp, _pin_unauth, _rdt_uuid, _scid, li_fat_id, hubspotutk, __hstc, __hssc, __hssrc, _mkto_trk, __kla_id

The runtime cannot delete third-party cookies. They live on the other party's domain.

↑↓ to move, Enter to open