Nemo's Parental Misguidance

    @finsweet/cookie-consent

    1.9.0 • Public • Published

    Fs Cookie Consent

    Cookie Consent for Webflow

    Cookie consent solution built for Webflow websites. With this tool you can fully design and customize GPDR and CCPA compliant cookie consent banners using Webflow's Designer.

    Table of contents:

    1. Getting Started
    2. Components
      1. Banner [Required]
      2. Manager [Optional]
      3. Preferences [Optional]
    3. Scripts
      1. Categories
      2. Example
      3. Using Google Tag Manager
      4. <noscript> tags
    4. IFrames
      1. Placeholder
      2. Example
    5. How it works
    6. Using Webflow Interactions
    7. Additional Options
    8. Storing Consent Records
    9. Consent Variations
      1. Opt-in [Recommended]
      2. Opt-out [Not-Recommended]
      3. Informational [Not-Recommended]
    10. Javascript API
    11. Important Notes

    Getting Started

    To get started with this product, you only need to:

    1. Place the components in all your project's pages, including all Collections, 404 and Search. Using Webflow's Symbols is strongly recommended to keep consistency across all the site.

    2. Make sure all the scripts are correctly set up.

    3. Import our Fs Cookie Consent solution code immediately after the last script. You can choose one of these options:

    [Recommended] Main version: This version does not support Internet Explorer.

    <script async src="https://cdn.jsdelivr.net/npm/@finsweet/cookie-consent@1/fs-cc.js"></script>

    IE support version: This version is heavier and less performant, but it supports legacy browsers like Internet Explorer.

    <script async src="https://cdn.jsdelivr.net/npm/@finsweet/cookie-consent@1/fs-cc-ie.js"></script>

    You can modify some functionalities of the Fs Cookie Consent tool by adding custom attributes to the script tag. Check Additional Options for more info.

    Components

    The solution consists of three different components:

    1. Banner [Required]
    2. Manager [Optional]
    3. Preferences [Optional]

    Banner

    The Banner is the main component and the only one required to have on the page. It will be displayed to new users who haven't yet confirmed their allowance or denial of cookies.

    How to set it up

    Place any Div or Section on the page and give it a fs-cc="banner" attribute. Inside it, you can place the following components:

    Component Required Allowed Elements Attribute Description
    Allow All Cookies Yes Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="allow" When clicked, all the cookies will be accepted and the banner will close.
    Deny All Cookies No Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="deny" When clicked, all the cookies except the essential ones will be denied and the banner will close.
    Close No Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="close" When clicked, the banner will just close without storing any consent from the user. The banner will keep displaying every time the page is refreshed until the user Allows or Denies the cookies.
    Open Preferences No Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="open-preferences" When clicked, the Preferences popup will open and the Banner will close.
    Interaction Trigger No Div (must be set to display: none) fs-cc="interaction" If this Div is placed inside the component, the script will use Webflow's Interactions to open/close it. Read Using Webflow Interactions for more information.
    Consents Form No Form None Within this form users can granulary choose what categories of cookies do they allow or deny. Read more at Consents Form.

    Optionally, the fs-cc="banner" component accepts the following attributes:

    Attribute Required Description
    fs-cc-scroll="disable" No If this attribute is set, scrolling will be disabled on the page when the component is displayed.
    fs-cc-display="PROPERTY_NAME" No If this attribute is set and no interaction is used for displaying the component, the default fade animation will set this display property.
    Avaiable properties are: block, flex, grid, inline-block, inline.
    Defaults to flex.

    Manager

    The Manager is an optional component that is always displayed on the page and lets the users open the Preferences component at any moment to modify their Cookies consents.

    How to set it up

    Place any Div or Section on the page and give it a fs-cc="manager" attribute. Inside it, you can place the following components:

    Component Required Allowed Elements Attribute Description
    Open Preferences Yes Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="open-preferences" When clicked, the Preferences popup will open.
    Interaction Trigger No Div (must be set to display: none) fs-cc="interaction" If this Div is placed inside the component, the script will use Webflow's Interactions to open/close it. Read Using Webflow Interactions for more information.

    Optionally, the fs-cc="manager" component accepts the following attributes:

    Attribute Required Description
    fs-cc-display="PROPERTY_NAME" No If this attribute is set and no interaction is used for displaying the component, the default fade animation will set this display property.
    Avaiable properties are: block, flex, grid, inline-block, inline.
    Defaults to flex.

    Preferences

    The Preferences is an optional component that allows the users to manually decide what categories of Cookies do they allow or deny.

    How to set it up

    Place any Div or Section on the page and give it a fs-cc="preferences" attribute. Inside it, you can place the following components:

    Component Required Allowed Elements Attribute Description
    Allow All Cookies No Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="allow" When clicked, all the cookies will be accepted and the banner will close.
    Deny All Cookies No Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="deny" When clicked, all the cookies except the essential ones will be denied and the banner will close.
    Close No Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="close" When clicked, the popup will just close without storing any consent from the user. The banner will keep displaying every time the page is refreshed until the user Allows or Denies the cookies.
    Interaction Trigger No Div (must be set to display: none) fs-cc="interaction" If this Div is placed inside the component, the script will use Webflow's Interactions to open/close it. Read Using Webflow Interactions for more information.
    Consents Form No Form None Within this form users can granulary choose what categories of cookies do they allow or deny. Read more at Consents Form.

    Optionally, the fs-cc="preferences" component accepts the following attributes:

    Attribute Required Description
    fs-cc-scroll="disable" No If this attribute is set, scrolling will be disabled on the page when the component is displayed.
    fs-cc-display="PROPERTY_NAME" No If this attribute is set and no interaction is used for displaying the component, the default fade animation will set this display property.
    Avaiable properties are: block, flex, grid, inline-block, inline.
    Defaults to flex.

    Consents Form

    Inside the Banner and the [Preferences][#preferences] components you can optionally add a form where users can granulary choose what categories of cookies do they allow or deny.

    How to set it up

    Place a Form with no attributes inside the component. Inside it, place the following elements:

    Element Required Allowed Elements Attribute Description
    Marketing Toggle Yes Checkbox fs-cc-checkbox="marketing" When checked, users will allow all Cookies from the Marketing category.
    Analytics Toggle Yes Checkbox fs-cc-checkbox="analytics" When checked, users will allow all Cookies from the Analytics category.
    Personalization Toggle Yes Checkbox fs-cc-checkbox="personalization" When checked, users will allow all Cookies from the Personalization category.
    Save Preferences Yes Submit Button
    Button
    Text Link
    Link Block
    Div
    Text Block
    fs-cc="submit" (Not required if the element is a Submit Button) When clicked, the new preferences from the user will be stored and the component will close.

    Scripts

    To avoid any third party script that uses cookies to be loaded when the page loads, you must include the following attribute to all of them:

    type="fs-cc"

    Adding this attribute will prevent the browsers from being able to parse the Javascript inside it, thus giving our Fs Cookie Consent solution the control over when the scripts will run.

    Additionally, you can give the scripts the following attribute to categorize them:

    fs-cc-categories="CATEGORY_NAME, CATEGORY_NAME, CATEGORY_NAME"

    Continue reading the categories section for more information.

    Categories

    By adding a fs-cc-categories attribute to the script, users will be able to granulary select what cookie categories do they allow when using the Preferences component.

    Name Attribute Description
    essential fs-cc-categories="essential" Required to enable basic website functionality. This category cannot be denied by the user.
    marketing fs-cc-categories="marketing" Used to deliver advertising that is more relevant to the user and his/her interests.
    analytics fs-cc-categories="analytics" These cookies help the website operator understand how its website performs, how visitors interact with the site, and whether there may be technical issues.
    personalization fs-cc-categories="personalization" These cookies allow the website to remember choices the users make (such as user name, language, or the region they are in) and provide enhanced, more personal features.

    You can set more than one category to a script by comma separating them. Example: fs-cc-category="marketing, analytics"

    Example

    Example: Google Analytics:

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" type="fs-cc" fs-cc-categories="analytics"></script>
    <script type="fs-cc" fs-cc-categories="analytics">
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
    
      gtag('config', 'G-XXXXXXXXXX');
    </script>

    Using Google Tag Manager

    If your website uses Google Tag Manager to dynamically load third party scripts, you must not set the GTM script to type="fs-cc". Instead, you should load it as usual.

    Our Fs Cookie Consent solution pushes the following events to the dataLayer when the correspondent category is consented by the user:

    • essential-activated
    • marketing-activated
    • analytics-activated
    • personalization-activated
    • uncategorized-activated

    You can use these events as Custom event triggers for loading your third party scripts after the user has explicitly given his/her consent.

    <noscript> tags

    The <noscript> tags are specifically designed to run when a user has Javascript disabled on the browser. This means that our Fs Cookie Consent cannot interact with them (as it's a Javascript based solution).

    To be fully compliant, make sure to remove any <noscript> tags included in your third party scripts.

    Example: Facebook Pixel.

    <!-- Facebook Pixel Code -->
    <script>
        !function(f,b,e,v,n,t,s)
        {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
        n.callMethod.apply(n,arguments):n.queue.push(arguments)};
        if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
        n.queue=[];t=b.createElement(e);t.async=!0;
        t.src=v;s=b.getElementsByTagName(e)[0];
        s.parentNode.insertBefore(t,s)}(window, document,'script',
        'https://connect.facebook.net/en_US/fbevents.js');
        fbq('init', '{your-pixel-id-goes-here}');
        fbq('track', 'PageView');
    </script>
    <noscript>
        <img height="1" width="1" style="display:none"
             src="https://www.facebook.com/tr?id={your-pixel-id-goes-here}&ev=PageView&noscript=1"/>
    </noscript>
    <!-- End Facebook Pixel Code -->

    As you can see, Facebook includes a <noscript> tag in the tracking pixel to be able to track users with disabled Javascript.

    A correct implementation of the Facebook Pixel would look like this:

    <!-- Facebook Pixel Code. Proper attributes have been added. -->
    <script type="fs-cc" fs-cc-categories="marketing">
        !function(f,b,e,v,n,t,s)
        {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
        n.callMethod.apply(n,arguments):n.queue.push(arguments)};
        if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
        n.queue=[];t=b.createElement(e);t.async=!0;
        t.src=v;s=b.getElementsByTagName(e)[0];
        s.parentNode.insertBefore(t,s)}(window, document,'script',
        'https://connect.facebook.net/en_US/fbevents.js');
        fbq('init', '{your-pixel-id-goes-here}');
        fbq('track', 'PageView');
    </script>
    <!-- End Facebook Pixel Code. The <noscript> tag has been removed -->

    IFrames

    Same as the scripts, <iframe> elements can be prevented from loading on the page until the user gives his correspondent consents.

    To set them up, replace the src attribute of the iFrame for:

    fs-cc-src="SOURCE_HERE"

    Additionally, you can categorize it like the scripts:

    fs-cc-categories="CATEGORY_NAME, CATEGORY_NAME, CATEGORY_NAME"

    Placeholder

    While the <iframe> is not loaded, you might want to display a placeholder element instead.

    If you set the following attribute to the <iframe>:

    fs-cc-placeholder="ELEMENT_SELECTOR"

    The matching element will be hidden once the iFrame is correctly loaded. The selector can be any valid CSS selector, like an #id, a .class or an [attribute].

    Example

    <iframe
      fs-cc-src="https://www.finsweet.com/"
      fs-cc-placeholder="#iframe-placeholder"
      width="100%"
      height="100%"
    ></iframe>

    How it works

    1. The Fs Cookie Consent script checks if the user has given consent to load the cookies. If not, the Banner is displayed asking for it.
    2. After the user has given his/her consent, our solution loads the consented categories' scripts.
    3. If the user changes his preferences at any time, our script erases all the cookies from his browser (except the HttpOnly ones, see Important Notes to read more) and re-runs only the correspondent scripts.
    4. The library is disabled if the visitor is a Crawling Bot to prevent indexing its content or if the visitor has DoNotTrack activated.

    Using Webflow Interactions

    By default, our Fs Cookie Consent script will apply a fade-in and fade-out animation to the components when showing/hiding them. Optionally, you can use Webflow Interactions to create your own custom animations.

    To do so, place a hidden Div (set to display: none) inside the component with the fs-cc="interaction" attribute. Then, bind a Mouse click (tap) interaction to it:

    • On 1st click will be used to display the component. Make sure the component is set to display: none as the initial state.
    • On 2nd click will be used to hide the component.

    Important: Only set the interaction to the trigger! Do not bind this interaction to any other element (like the buttons), our Fs Cookie Consent script will programatically click this hidden Div when needed and fire the correspondent interaction.

    Additional Options

    You can modify some of the behaviors of our Fs Cookie Consent tool by adding attributes to the main <script> tag.

    Attribute Required Description
    fs-cc-mode="opt-in" No Selected by default. Only the essential cookies are be loaded by default. Users are able to Allow or Deny the use of cookies. If allowed, cookies will start loading on the pages. More info at Opt-in Consent.
    fs-cc-mode="opt-out" No All cookies are be loaded by default even without the user's consent. Users are still able to Allow or Deny the use of cookies. If denied, cookies will stop loading on the pages. More info at Opt-out Consent.
    fs-cc-mode="informational" No The banner becomes informational only, considering that the user has already granted his consent thus allowing all cookies to be loaded by default. More info at Informational Consent.
    fs-cc-expires="NUMBER_OF_DAYS" No By default, the user's consent is stored for 120 days. You can change this expiry time with this attribute. Example for a 30 day duration: fs-cc-expires="30".
    fs-cc-endpoint="URL" No The library will send POST requests to this endpoint with the new consents. More info at Storing Consent Records.
    fs-cc-source="URL" No If set, the components (Banner, Manager and Preferences) will be fetched from the specified URL and rendered to the current page.
    This way, you won't have to manually place them into each single page of the website.
    Accepts both absolute URLs (fs-cc-source="https://example.com/components") and relative paths (fs-cc-source="/components").

    Example

    Example setting up Fs Cookie Consent in Opt-out mode and storing the user's consent for 60 days:

    <script async src="https://cdn.jsdelivr.net/npm/@finsweet/cookie-consent@1/fs-cc.js" fs-cc-mode="opt-out" fs-cc-expires="60"></script>

    Storing Consent Records

    Because consent under the GDPR is such an important issue, it’s mandatory to keep clear records and be able to demonstrate that the user has given consent. That's why our library offers the option of sending the consents to an API endpoint, so you can store them in your database.

    If the fs-cc-endpoint attribute is set, the library will make a POST request to the endpoint every time a user allow /denies / updates his consent. The request is done with the following payload:

    interface CookieConsentPayload {
      id: string; // UUID for the consent
      url: string; // Origin URL
      action: string; // Action performed by the user: allow, deny or submit
      userAgent: string; // User Agent of the user's browser
      bannerText: string; // The text that is displayed in the Banner component
      consents: {
        uncategorized: boolean;
        essential: boolean;
        personalization: boolean;
        analytics: boolean;
        marketing: boolean;
      };
    }

    You can use it for storing the record to your own database.

    Make sure you also store the following information for GDPR compliance:

    Property Description
    Anonymized IP The user's IP with the last digit replaced with a 0 to maintain anonymity.
    Timestamp The date and time when you store the consent.

    For how long? Nobody knows exactly, but many consider that 2 years is a safe bet.

    Javascript API

    You can use the Fs Cookie Consent Javascript API to further extend its functionalities. When loaded, you can access the instance at:

    window.FsCC

    Store

    The Store manages all the important states in the application. You can access the Store object at:

    window.FsCC.store

    Inside it, there are some methods and properties that you can access.

    Properties

    Property Value Description
    cookieMaxAge Number Sets how long will the user's consent will persist.
    mode informational, opt-in or opt-out Current mode. See Additional Options to see how to change it.
    scripts Object All the scripts that have the type="fs-cc" attribute, classified by category.

    Methods

    window.FsCC.store.userHasConfirmed = () => boolean; // Returns if the user has previously confirmed his allowance / denial of cookies
    window.FsCC.store.getConsents = () => Consents; // Returns the current stored consents, classified by category
    window.FsCC.store.getBannerText = () => string | null | undefined; // Returns the stored text of the banner
    window.FsCC.store.storeScript = (scriptData: ScriptData) => void; // Stores an additional script
    window.FsCC.store.storeIFrame = (iFrameData: IFrameData) => void; // Stores an additional iFrame
    window.FsCC.store.getStoredElements = () => (ScriptData | IFrameData)[]; // Returns the stored scripts and iFrames

    Consent Controller

    The Consent Controller runs all the logic behind the scenes. You can access the Consent Controller object at:

    window.FsCC.consentController

    Methods

    window.FsCC.consentController.updateConsents = (consents: Partial<Consents>) => void; // Stores new consents from the users and applies them to the corrsepondent scripts.

    Events

    window.FsCC.consentController.on('updateconsents', (consents: Partial<Consents>) => {
      console.log('The following consents were updated:', consents);
    });

    Banner

    You can access the Banner object at:

    window.FsCC.banner

    Properties

    Property Value Description
    ready Boolean Tells if the component was correctly mounted.
    isOpen Boolean Tells if the component is open / closed.

    Methods

    window.FsCC.banner.open = () => void; // Opens the banner.
    window.FsCC.banner.close = () => void; // Closes the banner.

    Events

    window.FsCC.banner.on('ready', (element: HTMLElement) => console.log('The component was correctly mounted!'));
    window.FsCC.banner.on('allow', () => console.log('An Allow all Cookies button was clicked.'));
    window.FsCC.banner.on('deny', () => console.log('A Deny all Cookies button was clicked.'));
    window.FsCC.banner.on('openpreferences', () => console.log('An Open Preferences button was clicked.'));
    window.FsCC.banner.on('close', () => console.log('The component was closed!.'));
    window.FsCC.banner.on('updateconsents', (consents: Partial<Consents>) => {
      console.log('The following consents were updated:', consents);
    });

    Manager

    You can access the Manager object at:

    window.FsCC.manager

    Properties

    Property Value Description
    ready Boolean Tells if the component was correctly mounted.
    isOpen Boolean Tells if the component is open / closed.

    Methods

    window.FsCC.manager.open = () => void; // Opens the manager.
    window.FsCC.manager.close = () => void; // Closes the manager.

    Events

    window.FsCC.manager.on('ready', (element: HTMLElement) => console.log('The component was correctly mounted!'));
    window.FsCC.manager.on('allow', () => console.log('An Allow all Cookies button was clicked.'));
    window.FsCC.manager.on('deny', () => console.log('A Deny all Cookies button was clicked.'));
    window.FsCC.manager.on('openpreferences', () => console.log('An Open Preferences button was clicked.'));
    window.FsCC.manager.on('close', () => console.log('The component was closed!.'));

    Preferences

    You can access the Preferences object at:

    window.FsCC.preferences

    Properties

    Property Value Description
    ready Boolean Tells if the component was correctly mounted.
    isOpen Boolean Tells if the component is open / closed.

    Methods

    window.FsCC.preferences.open = () => void; // Opens the preferences.
    window.FsCC.preferences.close = () => void; // Closes the preferences.

    Events

    window.FsCC.preferences.on('ready', (element: HTMLElement) => console.log('The component was correctly mounted!'));
    window.FsCC.preferences.on('allow', () => console.log('An Allow all Cookies button was clicked.'));
    window.FsCC.preferences.on('deny', () => console.log('A Deny all Cookies button was clicked.'));
    window.FsCC.preferences.on('openpreferences', () => console.log('An Open Preferences button was clicked.'));
    window.FsCC.preferences.on('close', () => console.log('The component was closed!.'));
    window.FsCC.preferences.on('updateconsents', (consents: Partial<Consents>) => {
      console.log('The following consents were updated:', consents);
    });

    Consent Variations

    There are three different ways of asking for consent to the users:

    1. Opt-in [Recommended]
    2. Opt-out [Not-Recommended]
    3. Informational [Not-Recommended]

    Opt-in Consent

    Cookies won't be loaded unless the user explicitly accepts them. This solution is the only GDPR and CCPA compliant one.

    To build this consent variation, make sure all the scripts are properly set up and that the users can Accept and Deny all the cookies.

    Opt-out Consent

    Cookies are loaded without the consent from the user unless he explicitly rejects them. This solution is not GDPR nor CCPA compliant and we strongly advise against it, as we cannot guarantee all cookies will be removed after the user denies them (read Important Notes for further information).

    To build this consent variation do not set the scripts to type="fs-cc" as your priority is to load them before asking for the user's consent. If the user denies them, the cookies will be removed from his/her browser.

    Informational Consent

    Users are just informed about the use of cookies on the site and do not have the option of rejecting them. This solution is valid for some countries but it's not GDPR nor CCPA compliant.

    To build this consent, you just need to add the Banner with an Allow All Cookies button.

    Important Notes

    Legal compliance of this tool

    Although our tool prevents third party scripts from being loaded unless the user explicitly allows them, and removes the correspondent cookies if the user decides not to allow them anymore, we cannot guarantee the removal of all cookies.

    Why? Some third party providers set HttpOnly cookies to the user's browser, which cannot be deleted using Javascript, thus preventing tools like ours from removing them.

    This is not a problem for 99% of the use cases, as your website will still be GDPR and CCPA compliant. But if you have specific legal compliance needs, we strongly advise seeking legal advice to make sure our Cookie Consent solution fits your project.

    Legal

    All content on this repository, as well as content throughout Finsweet's websites, platforms, services, or softwares, nor any portion thereof constitutes actual legal or regulatory advice, opinion, or recommendation by Finsweet.

    We are providing this free library to help you comply with cookie consent laws. If legal assistance is required, contact a lawyer.

    THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

    Install

    npm i @finsweet/cookie-consent

    DownloadsWeekly Downloads

    79

    Version

    1.9.0

    License

    none

    Unpacked Size

    362 kB

    Total Files

    8

    Last publish

    Collaborators

    • erikmejias
    • alexiglesias