gtag("consent", "update", ...){
"name": "CookieManager",
"view": "Default",
"section": "SectionFooter",
"settings": {
"daysEffective": 30,
"blocks": [
{
"title": "Sample title",
"content": "Sample content",
"toggle": {
"cookieCategory": "analytics",
"isEnabled": true,
"isReadOnly": false
}
},
...
],
"consentVersion": "Sample consent version",
"id": "Component Id",
"section": "SectionFooter",
"type": "NoirCookieManager",
"name": "CookieManager",
"configuredInContentApi": true,
"view": "Default",
"displayName": "",
"cssClass": ""
},
"translations": {
"cookieCardTitle": "Sample translation",
"cookieCardDescription": "Sample translation",
"cookieSettings": "Sample translation",
"...": "..."
}
}settings.idcomp-{{ id }}settings.daysEffective (number)settings.blocks[] (array)title (string)content (string, optional)toggle object with:cookieCategory (string, e.g. analytics, advertising)isEnabled (boolean)isReadOnly (boolean)settings.cssClass(UNDEFINED).settings.consentVersion (string)x-data='cookiemanagerdefault.initComponent(daysEffective, blocks, consentVersion, currentTab)'initComponent(...) returns Alpine state + actions for:servicesreusabledefault.setShopranosCookie(...)gtag("consent", "update", ...)initComponent(daysEffective, blocks, consentVersion, currentTab)daysEffective (number): how many days consent remains validblocks (array): dynamic categories (toggles) configured from settingsconsentVersion (string): used for re-consent when version changescurrentTab (string): initial tab in the details UIshowCookieBanner, showCookiesDetailsblocks, currentTab, consentVersion (normalized with ?? "")init()setExpirationDate()acceptPreferencesCookies(...), acceptAllCookies(...), rejectAllCookies(...)getCookieConsentTypes(), getCookieManagerConsentTypes()updateGoogleConsent(consentTypes)getCookie(name)consentVersion is normalized to an empty string when null/undefined. Make sure the backend always provides a version; otherwise the stored value becomes version- which reduces the usefulness of versioning.init()_shopranos cookie exists:showCookieBanner = true and returnsversion-this.consentVersionshowCookieBanner = truesetExpirationDate()daysEffectivenewDate.toISOString().slice(0, 19)slice(0, 19) removes timezone and milliseconds. That’s OK if the backend expects that format, but if you ever need timezone-safe behavior, store the full ISO string.daysEffective is undefined or not a number, date math can behave unexpectedly—ensure it’s always a valid number.acceptPreferencesCookies(acceptPreferencesCookiesErrorMessage) (async)setExpirationDate().getCookieManagerConsentTypes():requiredversion-<consentVersion>consentTypes.join(".")servicesreusabledefault.setShopranosCookie(value, expirationDate)true as the last argument to toast.add, i.e. sticky/persistent)updateGoogleConsent(consentTypes)showCookieBanner = falserequired included. Removing it would break the “strictly necessary cookies” contract.acceptAllCookies(acceptAllCookiesErrorMessage) (async)isEnabled = true for categories that:toggle.cookieCategory, and!isReadOnly)getCookieManagerConsentTypes()version-<consentVersion>setShopranosCookie(...)blocks in-place. That’s fine in Alpine, but if the same blocks object is also used elsewhere, be aware it’s shared state.rejectAllCookies(rejectAllCookiesErrorMessage) (async)block.toggle.isEnabled = falserequired.version-<consentVersion>updateGoogleConsent(["required"]) which denies analytics/adsconsentVersion is empty, you’ll store required.version-. Prefer always having a non-empty version.getCookieConsentTypes()_shopranos cookie and splits it by .:[] if cookie missing_shopranos value is treated as a simple dot-separated list. Avoid adding values that contain dots.getCookieManagerConsentTypes()["required"]["required"]block.toggle.isEnabled is true:block.toggle.cookieCategory.toLowerCase()cookieCategory existence before calling .toLowerCase(). In your current blocks model it exists when toggle exists, but if you ever allow toggle objects without category, add a guard:if (block?.toggle?.isEnabled && block.toggle.cookieCategory) ...updateGoogleConsent(consentTypes)gtag is not a function:console.error("gtag function not found.") and returnsad_user_data, ad_personalization, ad_storage, analytics_storage = "denied"analytics_storage if consent includes "analytics""advertising"gtag("consent", "update", consentState)gtag is missing.getCookie(name)document.cookie on ; <name>=nulldecodeURIComponent(...) when needed.$store.toastAlpine.store("toast").removeAll();
Alpine.store("toast").add(message, "ic-warning", "error", true);servicesreusabledefault.setShopranosCookie(value, expirationDate)/api/cookies) so consent is stored server-side as well.$store.toastservicesreusabledefault.setShopranosCookie(...)gtag (optional; if missing, consent update logs an error)_shopranos using a dot-separated format:required.analytics.advertising.version-<consentVersion>consentVersion changes, the component forces the banner to show again (re-consent).gtag isn’t available, Google Consent Mode won’t update (the component will still persist consent).x-data='cookiemanagerdefault.initComponent(daysEffective, blocks, consentVersion, currentTab)'showCookieBanner controls whether the UI is visible.showCookiesDetails toggles between:inforequiredsettings.blocks[] where toggle.cookieCategory exists.