Find out why your callback does not run and make it run once per event
A TermsFeed Free Cookie Consent callback seems not to run when Cookie Consent does not find a function, calls it at an unexpected moment, or when it throws. Cookie Consent ignores the callbacks of a second run(), and a page reload cancels the requests your callbacks start. Cookie Consent calls the 7 callbacks in the callbacks object of the configuration. Each value is a function, or the name of a function on window.
Add "debug": true to the configuration object and publish the change before you check anything. For each of the 7 callback events, the Console tab prints Calling Customer Callback: <name>, such as Calling Customer Callback: user_consent_saved. Cookie Consent prints this line whenever the callbacks option is set, even when it does not find a function to call. The line proves that the event happened, not that your code ran.
Cause 1: The callback name is misspelled or not on window
Cookie Consent ignores a callback key it does not know and a function name missing from window, with no error. A key such as user_consent_save or userConsentSaved never runs. A name given as a string runs only for a top-level function declaration or var in a classic script. Functions declared with let, const, or class, or inside a module, are not on window.
The Console tab shows Calling Customer Callback: user_consent_saved, but your function logs nothing.
Declare the function with function in a classic script, or pass the function itself instead of its name. This block passes the onConsentSaved function itself to user_consent_saved, which works whether or not the function is on window. Copy each key exactly from The 7 Cookie Consent callbacks.
<script type="text/javascript" src="https://www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent.js" charset="UTF-8"></script>
<script type="text/javascript" charset="UTF-8">
function onConsentSaved(details, reason) {
console.log('Cookie Consent answer', reason, details);
}
document.addEventListener('DOMContentLoaded', function () {
cookieconsent.run({
"notice_banner_type": "headline",
"consent_type": "express",
"palette": "dark",
"language": "en",
"website_name": "Example",
"user_consent_saved_on_page_load": true,
"callbacks": {
"user_consent_saved": onConsentSaved
},
"debug": true
});
});
</script>
Cause 2: The callback throws an error
An error inside your callback stops the rest of your callback, while Cookie Consent carries on with the consent flow. A Consent Mode update or a request placed after the failing line never goes out.
The Console tab shows the error as uncaught, in red, whether or not debug is on. With debug on, Cookie Consent prints Error in Customer Callback <name>: <error> first, such as Error in Customer Callback user_consent_saved: ReferenceError: gtag is not defined. Fix the line the error names, such as defining gtag in <head> before the Cookie Consent block, and reload.
Cause 3: The callback does not run for the event you expected
Each callback runs only at its own moments, so a callback you expected for an event sometimes never runs, by design. Compare the moment your code relies on with the moment each callback runs.
scripts_specific_loadedruns only for categories with tagged scripts. Cookie Consent calls it for a released category without tagged scripts only with"callbacks_force": true. Set the option on any page that grants consent signals from this callback.user_consent_savedruns on later page loads only with the option. For a visitor who answered on an earlier page, it runs only with"user_consent_saved_on_page_load": true.change_my_preferences_button_clickedruns only for the consent banner button. A link matched byopen_preferences_center_selectorand a call tocookieconsent.openPreferencesCenter()do not run it.notice_banner_loadedruns only when the consent banner appears. A visitor who answered does not see the consent banner, sonotice_banner_loadeddoes not run for that visitor, except in demo mode.scripts_all_loadedruns only when every category in use is accepted. A visitor who accepts some categories never triggers it.i_decline_button_clickednever runs from a click in implied mode or withnotice_banner_reject_button_hide. Implied consent does not show an "I decline" button, and the option hides it.
The "Save my preferences" button does not run a callback of its own, and user_consent_saved reports the saved answer instead. The close button of the Preferences Center discards the changes and does not run a callback.
With debug on, the Console tab does not print a Calling Customer Callback: <name> line for your callback at the moment you expected. That missing line shows that Cookie Consent did not call the callback at that moment.
Add "callbacks_force": true for scripts_specific_loaded or "user_consent_saved_on_page_load": true for later page loads, or move your code into user_consent_saved, which runs on every answer. Read when each option matters in When scripts_specific_loaded needs callbacks_force and Re-apply the saved choice on every page with user_consent_saved_on_page_load.
Cause 4: A second run() with its own callbacks is ignored
Cookie Consent runs once per page, so a second cookieconsent.run() keeps the first instance, and the options of the second call are ignored, callbacks included. A single-page app that calls run() on each route, or a second block from a theme or plugin, adds callbacks that never run.
With debug on in the first run(), the Console tab shows run() was already called on this page, the existing Cookie Consent is kept. Put every callback in one run() call. Code that loads later listens to the DOM events instead, such as document.addEventListener('cc_userConsentSaved', function (e) { console.log(e.reason, e.details); });, which carries details and reason as properties of a plain Event. Set up one run() per page with Single-Page Apps and Frameworks.
Cause 5: A page reload cancels requests from the callbacks
With page_refresh_confirmation_buttons on, Cookie Consent reloads the page after the "I agree", "I decline", and "Save my preferences" buttons, so the callbacks for that answer start right before the page unloads. user_consent_saved and i_decline_button_clicked run before the reload starts, and i_agree_button_clicked runs right after it starts. scripts_specific_loaded and scripts_all_loaded never run on the page that reloads; they run on the reloaded page instead, so consent signals granted from scripts_specific_loaded arrive there.
Turn on Preserve log in the Console tab and the Network tab, then answer. Chrome cancels a request started in user_consent_saved when its response has not arrived before the reload. A request with the status (canceled) in the Network tab points to this cause. Send a request that must complete with navigator.sendBeacon() or with fetch() and keepalive: true, which Chrome completes after the page reloads. Decide whether you need the reload with Reload the Page After Consent.
Callbacks that seem to fire twice
user_consent_saved runs 2 times on the page where a new visitor answers: once on page load and once for the answer. On the page load of a visitor who has not answered, it runs with reason 'page_load' and the categories released on page load, then with 'choice' when the visitor clicks.
The second argument tells the 2 calls apart. Check reason in your callback, and act on 'choice' alone for anything that records an answer, such as a log entry. Send a Google Consent Mode update on every call, whatever the reason, because each call carries the state the Google tags need on that page. A listener on cc_userConsentSaved next to the callback runs your code 2 times for each save, so keep one of them.
How to verify that each callback runs once per event
A working callback logs one line per event, with the reason you expect. Watch the console through an answer and a second page.
- Add
"debug": trueand"user_consent_saved_on_page_load": trueto the configuration and aconsole.log('Cookie Consent answer', reason, details)line to your callback, and publish the change. Close every private window, open a new one, open DevTools with F12, and load a page. - Open the Console tab and confirm your
page_loadline afterCalling Customer Callback: user_consent_saved. - Click the "I agree" button ("OK" in implied mode) and confirm one line with
choice. - Open a second page and confirm one line with
page_loadand the saved choice.