Home
Wiki
Home
Wiki
  1. 2. Components
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ShoppingListsButton
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Shipping
      • ShoppingLists
      • ShoppingListsNavbar
      • Toast
      • Users
      • VariantContent
      • WishlistButton
      • Services
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • Overview
        • theme.js
      • Css / Scss
        • Overview
        • ThemeClasses
    • 5. SDK
      • Overview
      • LiquidGlobals
      • ServicesSDK
  1. 2. Components

CookieManager

Purpose#

The CookieManager component renders the cookie consent banner and cookie preference UI.
It supports:
A simple banner view (title, description, primary actions)
A detailed settings view with vertical tabs:
Info
Required
Dynamic categories (from settings blocks)
Consent actions:
Accept all cookies
Reject all cookies
Accept preferences only (save selected categories)
Consent expiration/versioning:
If consent version changes, the banner is shown again
Google Consent Mode update via gtag("consent", "update", ...)

Inputs (model contract)#

Model shape (storefront example)#

{
  "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",
    "...": "..."
  }
}

Required fields#

settings.id
Used for wrapper id: comp-{{ id }}
settings.daysEffective (number)
Used to compute the consent expiration date (today + daysEffective).
settings.blocks[] (array)
Defines the dynamic cookie categories shown in the settings tabs.
Each block may include:
title (string)
content (string, optional)
toggle object with:
cookieCategory (string, e.g. analytics, advertising)
isEnabled (boolean)
isReadOnly (boolean)

Optional fields#

settings.cssClass
Applied to wrapper only when non-empty and not (UNDEFINED).
settings.consentVersion (string)
Used to determine whether previous consent is still valid.
If missing/changed, the banner is shown again.

JavaScript#

Global object#

The component exposes a global object:
It’s initialized from Liquid via Alpine:
x-data='cookiemanagerdefault.initComponent(daysEffective, blocks, consentVersion, currentTab)'
initComponent(...) returns Alpine state + actions for:
detecting whether consent is already set (and still valid)
persisting consent server-side via servicesreusabledefault.setShopranosCookie(...)
updating Google Consent Mode via gtag("consent", "update", ...)

initComponent(daysEffective, blocks, consentVersion, currentTab)#

What it does
Factory function that receives:
daysEffective (number): how many days consent remains valid
blocks (array): dynamic categories (toggles) configured from settings
consentVersion (string): used for re-consent when version changes
currentTab (string): initial tab in the details UI
Returns Alpine state:
showCookieBanner, showCookiesDetails
blocks, currentTab, consentVersion (normalized with ?? "")
Exposes methods:
init()
setExpirationDate()
acceptPreferencesCookies(...), acceptAllCookies(...), rejectAllCookies(...)
getCookieConsentTypes(), getCookieManagerConsentTypes()
updateGoogleConsent(consentTypes)
getCookie(name)
Advice
Keep the signature stable (Liquid contract).
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()#

What it does
Checks if the _shopranos cookie exists:
if missing → showCookieBanner = true and returns
Reads consent types from cookie and extracts the stored version token:
looks for an entry starting with version-
compares it to this.consentVersion
If version mismatch → consent is considered expired:
showCookieBanner = true
Advice
This implementation treats any version mismatch as “expired” (forces re-consent). That’s correct for policy changes.
It does not check a timestamp; expiration is handled by the cookie itself (daysEffective) and by version comparison.

setExpirationDate()#

What it does
Creates a date = now + daysEffective
Returns an ISO-like timestamp string:
newDate.toISOString().slice(0, 19)
Advice
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.
If daysEffective is undefined or not a number, date math can behave unexpectedly—ensure it’s always a valid number.

acceptPreferencesCookies(acceptPreferencesCookiesErrorMessage) (async)#

What it does
Clears existing toasts.
Computes expiration date via setExpirationDate().
Computes consent types from current enabled toggles via getCookieManagerConsentTypes():
always includes required
includes enabled categories from blocks
Appends version-<consentVersion>
Builds consent value:
dot-separated string: consentTypes.join(".")
Persists to backend via:
servicesreusabledefault.setShopranosCookie(value, expirationDate)
On failure:
shows error toast (with true as the last argument to toast.add, i.e. sticky/persistent)
returns
On success:
calls updateGoogleConsent(consentTypes)
hides banner: showCookieBanner = false
Advice
This path does not force-enable or force-disable toggles; it saves the current preferences the user selected.
Always keep required included. Removing it would break the “strictly necessary cookies” contract.

acceptAllCookies(acceptAllCookiesErrorMessage) (async)#

What it does
Clears toasts.
Computes expiration date.
Iterates all blocks and sets isEnabled = true for categories that:
have toggle.cookieCategory, and
are not read-only (!isReadOnly)
Computes consent types via getCookieManagerConsentTypes()
Appends version-<consentVersion>
Persists via setShopranosCookie(...)
On failure → toast + return
On success:
updates Google consent
hides banner
Advice
Read-only toggles are intentionally not modified (usually “Required” or non-optional categories).
This mutates 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)#

What it does
Clears toasts.
Computes expiration date.
Disables all blocks that are not read-only:
block.toggle.isEnabled = false
Persists minimal consent string:
required.version-<consentVersion>
On failure → toast + return
On success:
calls updateGoogleConsent(["required"]) which denies analytics/ads
hides banner
Advice
This still stores consent as “required + version”, so you can reliably detect that the banner was already shown (and what version it was for).
If consentVersion is empty, you’ll store required.version-. Prefer always having a non-empty version.

getCookieConsentTypes()#

What it does
Reads the _shopranos cookie and splits it by .:
returns [] if cookie missing
Advice
_shopranos value is treated as a simple dot-separated list. Avoid adding values that contain dots.

getCookieManagerConsentTypes()#

What it does
Builds the new consent list based on current UI toggles:
Starts with:
["required"]
If blocks are missing → returns ["required"]
For each block:
if block.toggle.isEnabled is true:
pushes block.toggle.cookieCategory.toLowerCase()
Advice
It doesn’t check 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)#

What it does
If gtag is not a function:
logs console.error("gtag function not found.") and returns
Creates default denied consent state:
ad_user_data, ad_personalization, ad_storage, analytics_storage = "denied"
Grants:
analytics_storage if consent includes "analytics"
all ad-related fields if consent includes "advertising"
Calls:
gtag("consent", "update", consentState)
Advice
This is Google Consent Mode v2 style fields (ad_user_data, ad_personalization, etc.). Make sure your GTM/gtag setup is compatible.
This function is intentionally “best effort”: consent is still persisted even if gtag is missing.

getCookie(name)#

What it does
Basic cookie reader:
splits document.cookie on ; <name>=
returns the cookie value or null
Advice
This is fine for simple cookie values. If the cookie can be URL-encoded, decode it with decodeURIComponent(...) when needed.

Global Alpine stores (used by CookieManager)#

$store.toast#

Used to display errors when persisting consent fails.
Common pattern:
Alpine.store("toast").removeAll();
Alpine.store("toast").add(message, "ic-warning", "error", true);

Services / API calls#

CookieManager persists consent via the services layer:
servicesreusabledefault.setShopranosCookie(value, expirationDate)
This posts to the backend (/api/cookies) so consent is stored server-side as well.

Dependencies#

Alpine.js
$store.toast
servicesreusabledefault.setShopranosCookie(...)
gtag (optional; if missing, consent update logs an error)

Notes#

Consent is stored in a cookie named _shopranos using a dot-separated format:
required.analytics.advertising.version-<consentVersion>
If consentVersion changes, the component forces the banner to show again (re-consent).
If gtag isn’t available, Google Consent Mode won’t update (the component will still persist consent).

Extras#

Template behavior (Liquid + Alpine)#

The component initializes via:
x-data='cookiemanagerdefault.initComponent(daysEffective, blocks, consentVersion, currentTab)'

Banner vs details view#

showCookieBanner controls whether the UI is visible.
showCookiesDetails toggles between:
the simple banner view
the detailed settings view (tabs)

Tabs#

The detailed view includes base tabs:
info
required
…and additional tabs generated from settings.blocks[] where toggle.cookieCategory exists.
Modified at 2026-04-14 13:18:56
Previous
Checkout
Next
FilterList
Built with