The version of Cookie Consent a site runs is the number in its script address, such as 4.2.0 in https://www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent.js. 4.2.0 is the version the TermsFeed generator writes today. A site on 4.0.0 or 4.1.0 keeps that version until someone changes the address.

Read the version from the script address in the page source or in the Network tab. Each version has its own address, and the loader at that address loads the script of the same version. Match the address in your page with its version.

Version Address the site loads
4.2.0 https://www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent.js
4.1.0 https://www.termsfeed.com/public/cookie-consent/4.1.0/cookie-consent.js
4.0.0 https://www.termsfeed.com/public/cookie-consent/4.0.0/cookie-consent.js

To check a live page, open Chrome DevTools, select the Network tab, type cookie-consent in the filter box, and reload. The requests show the version in their path. A self-hosted copy does not carry a version in its address, so search your copy: user_consent_saved_on_page_load appears only in 4.2.0, initial-data-cookie-consent in 4.1.0 and 4.2.0, and initial-cookie-consent in 4.0.0.

4.0.0 reads a different tag attribute from 4.1.0 and 4.2.0, so a script tagged for 4.0.0 never runs under the later versions. 4.2.0 changes the order in which released external scripts run and the nonce a released copy carries.

Compare your tagged scripts with the behavior of the version your site runs.

Behavior 4.0.0 4.1.0 4.2.0
Tag attribute cookie-consent="<category>" data-cookie-consent="<category>" data-cookie-consent="<category>"
Attribute on the released copy initial-cookie-consent initial-data-cookie-consent initial-data-cookie-consent
Order of external scripts As the browser loads them As the browser loads them Page order: an external script without async holds its category until it loads, fails, or 10 seconds pass
Nonce of the released copy nonce and data-nonce copied as plain attributes The nonce or data-nonce attribute value becomes the nonce The nonce of the tagged script itself, from its property, its nonce attribute, or data-nonce; the page nonce is never lent

4.2.0 reads 5 options that 4.0.0 ignores, 2 of them new in 4.2.0, and it parses every value more strictly. Check how the version your site runs reads each option your site sets.

Option or rule 4.0.0 4.1.0 4.2.0
On/off options Any truthy value means on, "false" included; debug and demo turn on only with the string "true" Same as 4.0.0 true or "true" in any case means on; "false" and any other value mean off
palette, notice_banner_type Case-sensitive; an unknown palette gives dark, an unknown notice_banner_type gives simple Same as 4.0.0 Any case; an unknown value gives the default (light, headline) with a warning
language The option alone, default en, exact internal codes such as en_gb; the browser language is never used Same as 4.0.0 The option when set, matched without case and with - or _; without it, the browser languages, then English
page_load_consent_levels An array only, case-sensitive; a single string does not release any optional category Same as 4.0.0 An array or one category as a string, in any case
website_name Shown only when longer than 2 characters Same as 4.0.0 Shown whenever it is not blank
Legal URLs Checked with a pattern; when both are set and either fails, the consent banner shows neither link Same as 4.0.0 Each URL checked on its own; only absolute http: or https: URLs
cookie_duration Not read Read, default 365; a non-numeric value gives a session cookie, a negative one expires the cookies at once Read, default 365; an invalid value gives 365 with a warning
callbacks, callbacks_force Not read Read Read
notice_banner_purposes_levels Not read Not read Read
user_consent_saved_on_page_load Not read Not read Read

All 3 versions write the same 3 cookies with the same names and the same JSON object format, so answers saved by 4.0.0 or 4.1.0 stay valid in 4.2.0. Compare how long the cookies last in each version, and when each version writes them.

Behavior 4.0.0 4.1.0 4.2.0
Lifetime 62 days for cookie_consent_level and cookie_consent_user_accepted; 3,650 days (10 years) for the token cookie_duration, default 365 days, for all 3 cookie_duration, default 365 days, for all 3
Page load of a visitor who answered Writes cookie_consent_level again; implied mode writes the token again Implied mode writes the token again Implied mode writes the token only when it is missing
A switch toggled in the Preferences Center Writes cookie_consent_level at once, even without saving Changes the choice in memory only Changes the choice in memory only; closing without saving discards it
Demo mode Writes cookie_consent_level and the token Same as 4.0.0 Does not write a cookie
cookie_consent_user_accepted without a valid cookie_consent_level No consent banner; under implied consent, all categories are released Same as 4.0.0 cookie_consent_user_accepted is removed, and the consent banner shows until the visitor answers again

4.0.0 has no callbacks, 4.1.0 has the 7 callbacks with 1 argument each, and 4.2.0 adds the reason argument and changes when several callbacks run. Callback code written for 4.1.0 runs at different moments in 4.2.0.

Check when each callback your site uses runs in each version before you upgrade.

Behavior 4.0.0 4.1.0 4.2.0
DOM events 9, without cc_userConsentSaved, cc_scriptsSpecificLoaded, cc_scriptsAllLoaded 12 12, with reason on cc_userConsentSaved
Callbacks None 7, each with 1 argument; errors are hidden 7, each called with 2 arguments, of which only user_consent_saved uses both; errors reach the console
user_consent_saved None (details), never on page loads of a visitor who answered (details, reason), and with user_consent_saved_on_page_load on page loads of a visitor who answered as well; always before any tagged script is released
notice_banner_loaded None Runs inside run() Runs after run() returns
change_my_preferences_button_clicked None For the consent banner button and for elements matched by the selector For the consent banner button only
scripts_specific_loaded None Runs without waiting for external scripts, at times twice for a category At most once per category, once its external scripts without async load, fail, or time out
scripts_all_loaded None Only after a click on the "I agree" button, after i_agree_button_clicked Whenever every category in use is released, after scripts_specific_loaded

4.2.0 keeps one instance per page, opens the Preferences Center from elements added later, and adds the accessibility behavior of a modal dialog.

Check the rows that touch your own code, such as the selector that opens the Preferences Center and the ids your CSS targets.

Behavior 4.0.0 4.1.0 4.2.0
A second run() call Adds a second consent banner and handles every click twice Same as 4.0.0 Keeps the first instance and returns the first object, or undefined while the first one is still starting
run() before <body> exists Throws an error when the consent banner must show Same as 4.0.0 Waits for DOMContentLoaded
A second copy of the script file on the page Replaces the cookieconsent global Same as 4.0.0 Skips itself; the first copy keeps the global
open_preferences_center_selector Bound once at run(); elements added later do nothing; href="#" jumps; an invalid selector stops the script Same as 4.0.0 Checked on every click; the default action is prevented; an invalid selector logs a warning
Languages 34, with Occitan in the menu 36, adding Estonian and Ukrainian 36; Occitan stays out of the menu unless it is the current language
Language menu Changes the Preferences Center only Same as 4.0.0 Changes the Preferences Center and the consent banner
Consent banner text One fixed sentence Same as 4.0.0 A sentence that lists the purposes of the categories in use
The "I agree" button with page_refresh_confirmation_buttons Releases scripts, then reloads Reloads without releasing Reloads without releasing
Accessibility aria-modal on every layout; no Escape and no focus return in the Preferences Center Same as 4.0.0 aria-modal and a focus trap on the interstitial and standalone layouts and the Preferences Center, Escape, focus return, translated accessible names
Ids of tabs, switches, and titles Unprefixed, such as title_your_privacy, tracking, cc-nb-title Same as 4.0.0 Prefixed, such as termsfeed-com---title_your_privacy, termsfeed-com---level-tracking, termsfeed-com---nb-title
Styles Several <style> elements without a nonce, added when the file loads Same as 4.0.0 One <style> element carrying the nonce from the script tag that loaded Cookie Consent, added at run()

The 4.2.0 ids and classes all carry the termsfeed-com--- or cc- prefix, except is-active and is-inactive. Check every 4.2.0 id and class in Free Cookie Consent DOM and CSS Reference.

A second loader snippet on the page does not load a second copy in any version. Its own run() call reaches the first copy, which in 4.0.0 and 4.1.0 adds a second consent banner.

Fixes TermsFeed ships in place under the 4.2.0 address

TermsFeed ships fixes to 4.2.0 under the same address, so a site on 4.2.0 runs them from its next page load without any change. Check your callbacks, styles, and scripts against these behaviors if they were written for an earlier 4.2.0 file.

  • user_consent_saved runs before tagged scripts. On every answer and on every page load where it runs, the callback runs before Cookie Consent releases any tagged script. After a click on the "I agree" or "I decline" button, it runs before i_agree_button_clicked or i_decline_button_clicked.
  • Page-load scripts run after run() returns. For a visitor who has not answered, inline tagged scripts run after run() returns, right after user_consent_saved with 'page_load'. The same holds for a visitor who answered when user_consent_saved_on_page_load is on.
  • cc_userChangedConsent carries the change. The event fires after a switch of the Preferences Center changes the choice in memory, with the category in level and the new state in accepted.
  • Switch ids carry the prefix. A category switch is termsfeed-com---level-<category> and its label termsfeed-com---level-<category>_label, so a selector such as #tracking matches nothing. Select a switch with input[name="tracking"] instead.
  • A lost cookie_consent_level cookie brings the consent banner back. Cookie Consent removes cookie_consent_user_accepted when cookie_consent_level is missing or invalid, so the consent banner shows until the visitor answers again.
  • The first copy on the page keeps running. A second copy of the script skips itself, and cookieconsent.openPreferencesCenter() keeps working.
  • The duplicate cookie warning shows without debug. Cookie Consent prints it with console.warn when subdomains set different cookie_domain values.

Upgrading takes 7 steps and about 15 minutes: change the address, then check the tags, options, callbacks, and styles that 4.2.0 reads differently. Make the change on a test copy of your site first.

  1. Replace 4.0.0 or 4.1.0 with 4.2.0 in the src of the loader tag, on every page or template that loads it.
  2. Rename the tag attribute on a 4.0.0 site: replace every cookie-consent=" attribute on tagged scripts with data-cookie-consent=". In a find-and-replace, search for cookie-consent=", with its leading space, and replace it with data-cookie-consent=", with its leading space, so the search skips attributes that already read data-cookie-consent=".
  3. Set each on/off option to the state you want, because the string "false" turns most on/off options on in 4.0.0 and 4.1.0 and off in 4.2.0. Set language to choose the language every visitor starts in, because 4.2.0 follows the browser without it.
  4. On a site that uses Google Consent Mode, keep the denied Consent Mode defaults as the first script in <head>, after only the charset meta. The defaults sit above the Google tags, the Google Tag Manager container, and the Cookie Consent block. Send Google Consent Mode updates from user_consent_saved with user_consent_saved_on_page_load: true, and grant other vendor signals from scripts_specific_loaded with callbacks_force: true. Filter the records you write in user_consent_saved on reason === 'choice'.
  5. Replace unprefixed ids, such as cc-nb-title (#cc-nb-title in CSS), in your CSS and scripts with the prefixed ids of 4.2.0.
  6. Under a nonce-based Content Security Policy, write the page nonce on the loader tag, and allow that nonce in style-src.
  7. Publish the changes and clear your page cache. Close every private window, open a new one, open the Network tab, load your site, filter for cookie-consent, and confirm the requests carry 4.2.0. Turn on debug: true, publish it, clear the page cache again, reload, and confirm that no Console line contains Invalid. Fix each option a warning names, then remove debug.

The cookie_consent_level and cookie_consent_user_accepted cookies written by 4.0.0 keep their 62-day expiry until the visitor answers again. Check the 4.2.0 Content Security Policy rules in Content Security Policy (CSP).

A self-hosted copy changes only when you replace the file, so an upgrade means downloading the 4.2.0 file and repeating the upgrade checks. Download https://www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent-code.js, replace your copy, and apply any text changes you made to the old copy again. Follow the download and serving steps in Self-Host Free Cookie Consent on Your Server.