npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@segment/consent-manager

v5.8.1

Published

Drop-in consent management plugin for analytics.js

Downloads

143,919

Maintainers

harksinghharksinghfhalim-segmentfhalim-segmentcfreecfreeldelossantosldelossantoshjoonpmhjoonpmceline-segmentceline-segmentpmcanseco-segmentpmcanseco-segmentmasiramasiraamillet89amillet89cholt002cholt002av-segmentav-segmentaghotikaraghotikarvikrant-segmentvikrant-segmentlarryatsegmentlarryatsegmentscruwys1scruwys1kyliepedersenkyliepedersenjinaparkjinaparkcdignam-segmentcdignam-segmentsegmentiosegmentiojrupasinghejrupasingheshayan-golafshanishayan-golafshanilateefatlateefatrajulvaderarajulvaderayash-twilioyash-twiliosowjanyasegmentsowjanyasegmentebru.odokebru.odokryanligonryanligonlpediredlalpediredlabrookstaylorjrbrookstaylorjrnithan-twilionithan-twiliodean-huynhdean-huynhwdbettswdbettsn2parkon2parkojayakrishnannairjayakrishnannairrhall-twiliorhall-twiliokarimkeshwanikarimkeshwanityson_segmenttyson_segmentjgabe13jgabe13bgamwellbgamwellpoojasegmentpoojasegmentmaryam.sharifmaryam.sharifwally.tgwally.tgsalolivaressalolivareserikdwerikdwchenxiangzhangchenxiangzhangjusteenjusteenmericssonmericssonprayansh-segmenttprayansh-segmenttjeremylarkinjeremylarkinbsneedbsneeddanieljackinsdanieljackinssegment-sethsegment-sethsayan-das-insayan-das-injames9446james9446priscilla.giattipriscilla.giattinlsunnlsundrew-thompsondrew-thompsonsegment-jsinghsegment-jsinghmcoulibalimcoulibaliandrius-segmentandrius-segmentvalerieernstvalerieernstnithin-bennynithin-bennyainatancincoainatancincoskondamuriskondamuriclintz.segclintz.segreplateroreplateroslenin-twilioslenin-twilioakashyap91akashyap91csayusocsayusoseanhan-segmentseanhan-segmentnevermore2022nevermore2022gilomergilomermarcelopvmarcelopveric.rognereric.rognerkdharaiyakdharaiyajon.anderson-at-segment.comjon.anderson-at-segment.comstacy.songstacy.songrexatsegmentrexatsegmentnickaguilarnickaguilarbradenbeckerbradenbeckerreneewangreneewangdan.laskydan.laskysam.tapiasam.tapialnambalnambavikramkumar19vikramkumar19mpriyad25mpriyad25jeremy.parkerjeremy.parkersmidgessmidgesnageshgolemnageshgolemsudojatinsudojatinpmaidpmaidsethsegmentsethsegmentjair.avilesjair.avilesmanali-bhosalemanali-bhosaleelmoselyeeelmoselyeechtoombschtoombspeterdemartinipeterdemartinivincen7tranvincen7tranmayur-pitalemayur-pitalelfdelossantoslfdelossantosemmy.byrneemmy.byrnefelttripfelttripsa-jsootersa-jsooterlluque-twiliolluque-twiliokevinburkesegmentkevinburkesegmentafsha-nazim-segafsha-nazim-segsong4yousong4youdavid.anusontarangkul.segmentdavid.anusontarangkul.segmentjyim008jyim008michaelghsegmichaelghsegacharles14acharles14aishikawakiaishikawakitwjosiahtwjosiahtanya.gupta.segmenttanya.gupta.segmentsindhusegmentsindhusegmentprabhnoor1997prabhnoor1997chihchun-twiliochihchun-twiliopmiller-twiliopmiller-twiliovbatanovvbatanovsimpixelatedsimpixelatedmcullenmeyermcullenmeyerneeharikakondipatineeharikakondipatieric-hydeeric-hydearunlalam-segmentarunlalam-segmentmschaszbergermschaszbergershuvrajit9904shuvrajit9904abhinavsurekaabhinavsurekavaradarajan-twvaradarajan-twimmanojimmanojblangtwilioblangtwiliojsh-wujsh-wujahood-twiliojahood-twiliosethnutetwiliosethnutetwiliorrivera-segmentrrivera-segmentsegment-adminsegment-adminbgillanbgillantcgilberttcgilbertmckern_segmentmckern_segmentmaneesh.dharma29maneesh.dharma29joetessyjoetessygkochar123gkochar123dominicbarnesdominicbarnesmugelstadmugelstadjalexy12jalexy12lerahulramlerahulrampmuninpmuninwhaider_twiliowhaider_twilioariel.silvestriariel.silvestris3gm3nts3gm3ntama0223ama0223shraddha-twilioshraddha-twiliomichelrmichelrbrandon.scott-segmentbrandon.scott-segmentjfehrman.segmentjfehrman.segmentprayansh-twilioprayansh-twiliodangmai-segmentdangmai-segmentaaronklishaaronklishbrianhumphreystwiliobrianhumphreystwiliormukundanrmukundanashwitha.bgashwitha.bgryanrouleau-segmentryanrouleau-segmentfunlufunlutdibaccotdibaccofauzy.yyfauzy.yynlubchenconlubchencoricardo.rossiricardo.rossisahilsharma0709sahilsharma0709arubiochavezarubiochavezphillip.thomasphillip.thomasjkusa_segmentjkusa_segmentrollcoderollcodemeg1000meg1000nainy.agrawalnainy.agrawalseg-rustybaileyseg-rustybaileyjbandi-twiliojbandi-twiliosaisagarkappaganthulasaisagarkappaganthulaforgetfulfellowforgetfulfellowdbaik-twilio-segmentdbaik-twilio-segmentpooja.patilpooja.patiljoe.ayoub.segmentjoe.ayoub.segmenthmohanram_seghmohanram_segbrian.aguirrebrian.aguirreenyi.asonyeenyi.asonyefarhan0581farhan0581tbrennanjtbrennanjparag.pandaparag.pandacherylj-segmentcherylj-segmentharsh.vardhanharsh.vardhansshaikh_segmentsshaikh_segmentxinghao.huangxinghao.huangshupadhyayshupadhyayjohn.lee1100john.lee1100kx-segmentkx-segmentsegment_fansegment_fandazu70dazu70sbhodiwalsbhodiwalsai-patanjalisai-patanjaliemilyjiaemilyjiay.yuy.yuea_segmentea_segmentyli119yli119pooyajpooyajsungju.jinsungju.jinconniechenconniechenbharath.boregowdabharath.boregowdaigracheva-twilioigracheva-twiliobenattwiliobenattwiliomarinheromarinheroankit.gupta.unthinkableankit.gupta.unthinkabledobrin.ganevdobrin.ganevalfrimpongalfrimpongbrandonheyer-segmentbrandonheyer-segmentalecjacobs-segmentalecjacobs-segmentcjo2cjo2yashnit-segmentyashnit-segmentdltnbrks-segmentdltnbrks-segmentachandrashekaranachandrashekaranhimanshuphhimanshuphpraguptapraguptatw-dgarciatw-dgarciaalayvoraalayvoraaparna.singhalaparna.singhalynguyenynguyentimmyzsearcytimmyzsearcylweimersegmentlweimersegmentanton-vylushchakanton-vylushchakazhaotwilioazhaotwiliorokatyalrokatyalkjoerreskjoerresmsarafmsarafvikakumarvikakumaraditi.raveeshaditi.raveeshchenchensegmentcomchenchensegmentcomsanket.mishrasanket.mishraodoren_segmentodoren_segmentjxin_twiliojxin_twiliorcheedhallarcheedhallajbasiglio-segmentjbasiglio-segmentviveksainaneesegmentviveksainaneesegmentpriyanshispriyanshispreetyppreetypakash.gautam07akash.gautam07nanotimmnanotimmyshkpryshkprsrivig21srivig21ssunejassunejabala.singareddybala.singareddymoyara2moyara2arjunbhandagearjunbhandageakodankiryakodankiryrodhilton_twiliorodhilton_twiliocdelaomartinezcdelaomartinezgbatragbatraspencerattickspenceratticksegmentseansegmentseansundareswar.jayakumarsundareswar.jayakumarvaibhavnandavaibhavnandabannapplebannapplesrishti-nemasrishti-nemaar7devar7devgsolis_segmentgsolis_segmentitsarijitrayitsarijitraybhavanki-segmentbhavanki-segmentnitinpm432nitinpm432nikumarsegmentnikumarsegmentnanette.ranesnanette.ranesamigandhiamigandhiguthriesegmentguthriesegmentmiguelpdiaz8miguelpdiaz8mansarimansarisandhya16sandhya16hema-bahirwani-segmenthema-bahirwani-segmentbnakkinabnakkinapraveenugiripraveenugiriighorelaighorelanemery-segmentnemery-segmentwlumsegmentwlumsegmentnat-gridnat-gridneedcaffeineneedcaffeinekbhargavaram-sgkbhargavaram-sgirfan.ali.segmentirfan.ali.segmentharsh-joshi99harsh-joshi99ed-twilion-npmed-twilion-npmaubreysineaubreysinelight-bringer-blrlight-bringer-blrsethgrid_segmentsethgrid_segmentjibrangjibrangseg-leonelsanchesseg-leonelsanchessmccoy-twiliosmccoy-twiliodevthaledevthaleandwivediandwivedipoojapatilsegpoojapatilseggaprabhugaprabhuapackerapackermonusegmentmonusegmentehydesegmentehydesegment

Readme

consent-manager build status

Drop-in consent management plugin for analytics.js

StoryBook

Segment Consent Manager

The Segment Consent Manager is an analytics.js add-on with support to consent management.

At its core, the Consent Manager empowers your visitors to control and customize their tracking preferences on a website. They can opt out entirely of being tracked, or selectively opt out of tools in which they don’t want their information stored.

It works by taking control of the analytics.js load process to only load destinations that the user has consented to and not loading analytics.js at all if the user has opted out of everything. The user's tracking preferences are saved to a cookie and sent as an identify trait (if they haven't opted out of everything) so that you can also access them on the server-side and from destinations (warehouse).

Segment works to ensure the Consent Manager Tech Demo works with most of our product pipeline. We cannot ensure it works in your specific implementation or website. Please contact our Professional Services team for implementation support. Please see the License.txt included.

Please note, Consent Manager is not currently compatible with Personas. Personas may send user data to destinations the user has explicitly opted out of for data collection.

Features

  • Give users the ability to opt-in or opt-out to tracking.
  • Fine grained control of tools or categories used for tracking.
  • 30s setup with a drop in script tag.
  • Or fully customizable UI/UX through React components.
  • EU traffic detection through @segment/in-eu.
  • Ability for visitors to reconsent and change preferences.
  • Automatically updates to reflect the destinations you have enabled in Segment.
  • 5.0.0: Consent Manager will add consent metadata to the context of all track calls:

Track call message payloads will be extended to include Consent metadata in the context object:

{
  "context": {
    "campaign": {},
    "consent": {
      "categoryPreferences": {
        "Amplitude": true,
        "Customer.io": true,
        "Google Analytics": true,
        "Webhooks": true
      },
      "defaultDestinationBehavior": "disable",
      "destinationPreferences": {
        "Amplitude": true,
        "Customer.io": true,
        "Google Analytics": true,
        "Webhooks": true
      }
    }
  },
  "event": "Send Track Event Clicked",
  "integrations": {
    "All": false,
    "Amplitude": true,
    "HubSpot": false,
    "Salesforce": false,
    "Segment.io": true
  }
}

Breaking Changes: Version 5.0.0 and above require that your analytics.js snippet include the method addSourceMiddleware in the analytics.methods array:

analytics.methods = [
  'trackSubmit',
  'trackClick',
  'trackLink',
  'trackForm',
  'pageview',
  'identify',
  'reset',
  'group',
  'track',
  'ready',
  'alias',
  'debug',
  'page',
  'once',
  'off',
  'on',
  'addSourceMiddleware' // This method is necessary for Consent Manager to forward consent metadata.
]

Usage

The Segment Consent Manager can be used in several ways, depending on how custom you want your visitor's experience to be.

To get started, make sure you're using the latest version of the analytics.js snippet (4.1.0 or above) and remove the analytics.load("YOUR_WRITE_KEY"); call (so the consent manager can manage the loading process). Then continue onto one of the implementation methods below.

Standalone Script

The standalone script is a prebuilt bundle that uses the ConsentManager React component with Preact (a lightweight React alternative). It's best for if you want to get up and running quickly or you don't have a preexisting React setup.

Include the consent manager script tag after your analytic.js snippet and add your own custom copy. The standalone script can be configured in one of two ways, via data attributes for simple usage or via a global callback function for advanced usage. Both methods allow the consent manager script to be loaded async.

Options

All of the ConsentManager options are supported with the addition of these options:

container

Type: string

CSS selector to the DOM element that will host the consent banner. It should be an empty DOM element (usually a <div>) because the consent manager will replace any existing DOM elements inside it. The element must also exist on the page before the script is executed.

You can also control the positioning of the consent banner by applying styles to the container element (optional). E.g:

#target-container {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
}
<div id="target-container"></div>

Globals

The following global variables are also exposed:

  • consentManager.version - Version of the consent manager.
  • consentManager.openConsentManager() - Opens the consent manager preferences dialog.
  • consentManager.doNotTrack() - Utility function that returns the user's Do Not Track preference (normalises the cross browser API differences). Returns true, false or null (no preference specified).
  • consentManager.inEU() - The @segment/in-eu inEU() function.
  • consentManager.preferences - Returns an instance of PreferencesManager with the following helper functions:
    • loadPreferences - returns the cookie value for consent preferences
    • savePreferences - allows for managing the consent cookie programatically (useful if you want to re-hydrate consent from your own database or prefill consent options)
    • onPreferencesSaved(callback) - allows for subscribing to changes in preferences.

Callback Function

All the options are supported. The callback function also receives these exports:

  • React - Reference to the Preact library (the API is React compatible). Useful for if you need to use virtual DOM in your content.
  • version - Version of the consent manager.
  • openConsentManager() - Opens the consent manager preferences dialog.
  • doNotTrack() - Utility function that returns the user's Do Not Track preference (normalises the cross browser API differences). Returns true, false or null (no preference specified).
  • inEU() - The @segment/in-eu inEU() function.
  • consentManager.preferences - Returns an instance of PreferencesManager with the following helper functions:
    • loadPreferences - returns the cookie value for consent preferences
    • savePreferences - allows for managing the consent cookie programatically (useful if you want to re-hydrate consent from your own database or prefill consent options)
    • onPreferencesSaved(callback) - allows for subscribing to changes in preferences.
<script>
  window.consentManagerConfig = function(exports) {
    var React = exports.React
    var inEU = exports.inEU

    var bannerContent = React.createElement(
      'span',
      null,
      'We use cookies (and other similar technologies) to collect data to improve your experience on our site. By using our website, you՚re agreeing to the collection of data as described in our',
      ' ',
      React.createElement(
        'a',
        { href: '/docs/legal/website-data-collection-policy/', target: '_blank' },
        'Website Data Collection Policy'
      ),
      '.'
    )
    var bannerSubContent = 'You can change your preferences at any time.'
    var preferencesDialogTitle = 'Website Data Collection Preferences'
    var preferencesDialogContent =
      'We use data collected by cookies and JavaScript libraries to improve your browsing experience, analyze site traffic, deliver personalized advertisements, and increase the overall performance of our site.'
    var cancelDialogTitle = 'Are you sure you want to cancel?'
    var cancelDialogContent =
      'Your preferences have not been saved. By continuing to use our website, you՚re agreeing to our Website Data Collection Policy.'

    return {
      container: '#target-container',
      writeKey: '<your-segment-write-key>',
      shouldRequireConsent: inEU,
      bannerContent: bannerContent,
      bannerSubContent: bannerSubContent,
      preferencesDialogTitle: preferencesDialogTitle,
      preferencesDialogContent: preferencesDialogContent,
      cancelDialogTitle: cancelDialogTitle,
      cancelDialogContent: cancelDialogContent
    }
  }
</script>

<script
  src="https://unpkg.com/@segment/[email protected]/standalone/consent-manager.js"
  defer
></script>

ConsentManager

The ConsentManager React component is a prebuilt consent manager UI (it's the one we use on https://segment.com) that uses the ConsentManagerBuilder component under the hood. To use it, just mount the component where you want the consent banner to appear and pass in your own custom copy.

Note: Consent Manager is React-based so is not currently compatible with other frameworks such as Vue.js or Angular. In case you want to use it in another framework that is not React, you should use the Standalone implementation.

Install

Using npm:

npm install @segment/consent-manager

Using yarn:

yarn add @segment/consent-manager

Example

import React from 'react'
import { ConsentManager, openConsentManager } from '@segment/consent-manager'
import inEU from '@segment/in-eu'

export default function() {
  const bannerContent = (
    <span>
      We use cookies (and other similar technologies) to collect data to improve your experience on
      our site. By using our website, you’re agreeing to the collection of data as described in our{' '}
      <a href="/docs/legal/website-data-collection-policy/" target="_blank">
        Website Data Collection Policy
      </a>
      .
    </span>
  )
  const bannerSubContent = 'You can change your preferences at any time.'
  const preferencesDialogTitle = 'Website Data Collection Preferences'
  const preferencesDialogContent =
    'We use data collected by cookies and JavaScript libraries to improve your browsing experience, analyze site traffic, deliver personalized advertisements, and increase the overall performance of our site.'
  const cancelDialogTitle = 'Are you sure you want to cancel?'
  const cancelDialogContent =
    'Your preferences have not been saved. By continuing to use our website, you՚re agreeing to our Website Data Collection Policy.'

  return (
    <div>
      <ConsentManager
        writeKey="<your-segment-write-key>"
        shouldRequireConsent={inEU}
        bannerContent={bannerContent}
        bannerSubContent={bannerSubContent}
        preferencesDialogTitle={preferencesDialogTitle}
        preferencesDialogContent={preferencesDialogContent}
        cancelDialogTitle={cancelDialogTitle}
        cancelDialogContent={cancelDialogContent}
      />

      <button type="button" onClick={openConsentManager}>
        Website Data Collection Preferences
      </button>
    </div>
  )
}

Example in Next.js

In Next.js we do not have an html file where to inject the script. Here we will use the Script component to inject the snippet provided by Segment.

import React from 'react'
import Script from 'next/script'
import { ConsentManager, openConsentManager } from '@segment/consent-manager'

export default function Home() {
  const bannerContent = (
    <span>
      We use cookies (and other similar technologies) to collect data to improve your experience on
      our site. By using our website, you’re agreeing to the collection of data as described in our{' '}
      <a href="/docs/legal/website-data-collection-policy/" target="_blank">
        Website Data Collection Policy
      </a>
      .
    </span>
  )
  const bannerSubContent = 'You can change your preferences at any time.'
  const preferencesDialogTitle = 'Website Data Collection Preferences'
  const preferencesDialogContent =
    'We use data collected by cookies and JavaScript libraries to improve your browsing experience, analyze site traffic, deliver personalized advertisements, and increase the overall performance of our site.'
  const cancelDialogTitle = 'Are you sure you want to cancel?'
  const cancelDialogContent =
    'Your preferences have not been saved. By continuing to use our website, you՚re agreeing to our Website Data Collection Policy.'

  return (
    <div>
      <Script
        id="show-banner"
        dangerouslySetInnerHTML={{
          __html: `!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.src="https://cdn.segment.com/analytics.js/v1/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._loadOptions=e};;analytics.SNIPPET_VERSION="4.13.2";
          analytics.page();
          }}();`
        }}
      />

      <main>
        <ConsentManager
          writeKey="5V8KznnIFIDh1ejQLbmX7ikfSRa6r8bF"
          bannerContent={bannerContent}
          bannerSubContent={bannerSubContent}
          preferencesDialogTitle={preferencesDialogTitle}
          preferencesDialogContent={preferencesDialogContent}
          cancelDialogTitle={cancelDialogTitle}
          cancelDialogContent={cancelDialogContent}
          bannerActionsBlock={true}
        />

        <button type="button" onClick={openConsentManager}>
          Website Data Collection Preferences
        </button>
      </main>
    </div>
  )
}

ConsentManager Props

This section lists the configurable props you can change when loading the out of the box Consent Manager. In this demo, these are all the props you can pass into the returned preferences object.

writeKey

Type: string Default: none

The write key analytics.js should be loaded with.

You can find more information here. https://segment.com/docs/connections/find-writekey

otherWriteKeys

Type: array<string> Default: []

Write keys for other sources so you can include destinations they use in the Consent Manager tool list. This only displays destinations that are not connected to the primary writeKey.

The user’s consent preferences for these tools are not sent to these additional sources, but they are added to the identify call the Consent Manager sends to Segment. The user’s preferences can then be added to a raw data destination (like a data warehouse) or to a user profile in Personas.

shouldRequireConsent

Type: function Default: () => true

Callback function that determines if consent is required before tracking begins. Set to true to show the consent banner, otherwise return false to not show consent banner and start tracking immediately.

The function can return a Promise that resolves to a boolean.

initialPreferences

Type: object Default: {}

Object that opts into users into tracking for the different tracking categories. For example {‘Functional’:true}

closeBehavior

Type: string or function Default: dismiss

This option sets the default behavior for the x (close) button on the Consent Manager banner. Available options:

  • “dismiss” - dismisses the banner, but doesn't save or change any preferences. Analytics.js won’t load until consent is given.
  • “accept”- assume consent across every category.
  • ”deny” - denies consent across every category.

closeBehavior can also be customized - i.e. don't load some categories, but load everything else. For example, if you wanted to load everything except advertising, you could pass the following as closeBehavior:

closeBehavior={
  (categories) => ({
    ...categories,
    advertising: false
  })
}
implyConsentOnInteraction

Breaking Change (versions < 3.0.0 will default this option true)

Type: boolean Default: false (as of 3.0.0)

Determines whether or not consent should be implied if the user interacts with the website by clicking anywhere outside the Consent Manager banner.

defaultDestinationBehavior

Type: string Default: disable

Determines what the Consent Manager does if the user has already made consent selections and it detects new destination tools. (This is determined by checking if the user already has a cookie set on their browser.)

This is relevant when you've added a connected a new destination to any of the sources managed by Consent Manager.

Options:

  • disable (default) - When you add new destinations, they are set to “disabled” unless a user updates their consent selections by default.
  • enable - When you add new destinations, they are set to “enabled” unless a user updates their consent selections.
  • imply - When you add new destinations, they are enabled or disabled based on the category to which they belong and the user's previous consent to that category. For example, if a user already consented to the marketingAndAnalytics category, and you add a new destination which is in the Analytics category, that destination will be enabled until the user updates their consent selections.
  • ask - When you add new destinations, the Consent Manager automatically opens the preferences dialog on initialization, and asks the user for their consent again.
cookieDomain

Type: string Default: the top most domain and all sub domains

The domain the tracking-preferences cookie should be scoped to.

bannerContent

Type: PropTypes.node

The content of the consent banner.

bannerSubContent

Type: string

The call to action under the primary text in the Consent Manager banner.

bannerActionsBlock

Type: function(object) | boolean

The flag or function to render the actions block. If true value is passed - will render the default buttons block with Accept all and Deny all (required for the GDPR compliance). if the function is passed - will render the passed function into a actions block placeholder.

Function props:

  • acceptAll: () => void - accept all cookies and close the banner
  • denyAll: () => void - deny all cookies and close the banner
  • changePreferences: () => void - open the dialog
bannerTextColor

Type: string Default: #fff

The color of the consent banner text.

bannerBackgroundColor

Type: string Default: #1f4160

The color of the consent banner background.

bannerHideCloseButton

Type: boolean Default: false

Hide the close button of the consent banner.

bannerAsModal

Type: boolean Default: false

Show the consent banner as a modal, blocking the interaction while it is not accepted/rejected.

preferencesDialogTitle

Type: PropTypes.node Default: Website Data Collection Preferences

The title of the preferences dialog.

preferencesDialogContent

Type: PropTypes.node

The top descriptive content of the preferences dialog.

cancelDialogTitle

Type: PropTypes.node Default: Are you sure you want to cancel?

The title of the cancel dialog.

cancelDialogContent

Type: PropTypes.node

The text displayed in the cancel dialog box.

customCategories

Type: PropTypes.object Default: undefined

An object that represents custom consent categories, and which tools are included in these categories. For example, for CCPA compliance, you could create a custom “Do Not Sell” category and list relevant destinations to it.

Note: Calling the customCategories object will overwrite the prebuilt categories (Analytics, Functional, Targeting and Advertising) provided by Consent Manager. Those categories will need to be redeclared inside customCategories. You can find examples here and here.

const customCategories = {
  'New Category': {
    purpose: 'A new consent category to capture more granular consent groupings',
    integrations: ['Google Adwords (Classic)', 'Amplitude', 'Slack']
  }
}

The values for integrations should be an integration's creationName (integration.creationName). You can find examples of that by going to https://cdn.segment.com/v1/projects/<writeKey>/integrations

preferencesDialogTemplate

Type: PropTypes.object Default:

{
  headings: {
    allowValue: 'Allow',
    categoryValue: 'Category',
    purposeValue: 'Purpose',
    toolsValue: 'Tools'
  },
  checkboxes: {
    noValue: 'No',
    yesValue: 'Yes'
  },
  actionButtons: {
    cancelValue: 'Cancel',
    saveValue: 'Save'
  },
  cancelDialogButtons: {
    cancelValue: 'Yes, Cancel',
    backValue: 'Go Back'
  },
  categories: [
    {
      key: 'functional',
      name: 'Functional',
      description:
        'To monitor the performance of our site and to enhance your browsing experience.',
      example: 'For example, these tools enable you to communicate with us via live chat.'
    },
    {
      key: 'marketing',
      name: 'Marketing and Analytics',
      description:
        'To understand user behavior in order to provide you with a more relevant browsing experience or personalize the content on our site.',
      example:
        'For example, we collect information about which pages you visit to help us present more relevant information.'
    },
    {
      key: 'advertising',
      name: 'Advertising',
      description:
        'To personalize and measure the effectiveness of advertising on our site and other websites.',
      example:
        'For example, we may serve you a personalized ad based on the pages you visit on our site.'
    },
    {
      key: 'essential',
      name: 'Essential',
      description: 'We use browser cookies that are necessary for the site to work as intended.',
      example:
        'For example, we store your website data collection preferences so we can honor them if you return to our site. You can disable these cookies in your browser settings but if you do the site may not work as intended.'
    }
  ]
}

An object that represents the text fields of the preferences dialog and allows customizing them. We recommend copying the default object and changing the fields as necessary.

Note: All fields are optional. If they are not included in the template (object) the default fields will be used.

Note 2: For categories, you need to provide the key in order to map all the values properly.

ConsentManagerBuilder

The ConsentManagerBuilder React component is a low level render props component for building your own consent manager UI. It abstracts away all the logic for fetching destinations, checking/saving consent and loading analytics.js.

Note: ConsentManagerBuilder is React-based so is not currently compatible with other frameworks such as Vue.js or Angular. In case you want to use it in another framework that is not React, you should use the Standalone implementation.

Install

Using npm:

npm install @segment/consent-manager

Using yarn:

yarn add @segment/consent-manager

Example

For a more detailed/advanced example, checkout the ConsentManager implementation.

import React from 'react'
import { ConsentManagerBuilder } from '@segment/consent-manager'

export default function() {
  return (
    <ConsentManagerBuilder writeKey="<your-segment-write-key>">
      {({ destinations, preferences, setPreferences, saveConsent }) => (
        <div>
          <h2>Tracking tools</h2>
          <ul>
            {destinations.map(destination => (
              <li key={destination.id}>
                <label>
                  <input
                    type="checkbox"
                    checked={Boolean(preferences[destination.id])}
                    onChange={() =>
                      setPreferences({
                        [destination.id]: !preferences[destination.id]
                      })
                    }
                  />
                  {destination.name}
                </label>
              </li>
            ))}
          </ul>

          <button type="button" onClick={() => saveConsent()}>
            Save
          </button>
          <button type="button" onClick={() => saveConsent(true)}>
            Allow all
          </button>
          <button type="button" onClick={() => saveConsent(false)}>
            Deny all
          </button>
        </div>
      )}
    </ConsentManagerBuilder>
  )
}

ConsentManagerBuilder Props

children

Type: function

The render props function that returns your UI.

writeKey

Type: string

The write key analytics.js should be loaded with.

otherWriteKeys

Type: array<string> Default: []

Other write keys that you want to load destination information for. This is useful for including your server-side destinations in the consent manager, so that you can easily apply the user's tracking preferences to your server-side analytics too. No data will be sent to these write keys.

shouldRequireConsent

Type: function Default: () => true

Callback function that determines if consent is required before tracking can begin. Return true to show the consent banner and wait for consent (if no consent has been given yet). Return false to not show the consent banner and start tracking immediately (unless the user has opted out). The function can return a Promise that resolves to a boolean.

initialPreferences

Type: object Default: {}

The initial value of the preferences. By default it should be an object map of {destinationId: true|false|'N/A'}. If you're using mapCustomPreferences it should be an object map of your custom preferences' default values.

defaultDestinationBehavior

Type: string Default: disable

Determines what the Consent Manager does if the user has already made consent selections and it detects new destination tools. (This is determined by checking if the user already has a cookie set on their browser.)

This is relevant when you've added a connected a new destination to any of the sources managed by Consent Manager.

Options:

  • disable (default) - When you add new destinations, they are set to “disabled” unless a user updates their consent selections by default.
  • enable - When you add new destinations, they are set to “enabled” unless a user updates their consent selections.
  • imply - When you add new destinations, they are enabled or disabled based on the category to which they belong and the user's previous consent to that category. For example, if a user already consented to the marketingAndAnalytics category, and you add a new destination which is in the Analytics category, that destination will be enabled until the user updates their consent selections.
  • ask - When you add new destinations, the Consent Manager automatically opens the preferences dialog on initialization, and asks the user for their consent again.

This setting also also affects Replays to new destinations. Only disable and enable apply to these replays. If you set defaultDestinationBehavior to imply, Segment interprets this as enable during a replay.

mapCustomPreferences

Type: function Default: undefined

Callback function allows you to use a custom preferences format (e.g: categories) instead of the default destination based one. The function gets called during the consent saving process and gets passed (destinations, preferences). The function should return {destinationPreferences, customPreferences} where destinationPreferences is your custom preferences mapped to the destinations format ({destiantionId: true|false}) and customPreferences is your custom preferences if you changed them in the callback (optional).

cookieDomain

Type: string Default: the top most domain and all sub domains

The domain the tracking-preferences cookie should be scoped to.

shouldReload

Type: boolean Default: true

Reload the page if the trackers have already been initialized so that the user's new preferences can take effect.

devMode

Type: boolean Default: false

Disable the analitics.load to make local testing.

ConsentManagerBuilder Render Props

destinations

Type: array<object> Default: []

Destinations enabled for the provided write keys. Each destination contains these properties:

{
  id,
  name,
  description,
  website,
  category
}
newDestinations

Type: array<object> Default: []

New destinations that have been enabled since the user last gave consent.

preferences

Type: object Default: {}

The current preferences in state. By default if should be in the format of {destinationId: true|false}, but if you're using mapCustomPreferences the object map can be in any format you want. Note: this isn't the saved preferences.

destinationPreferences

Type: object Default: {}

The current destination specific preferences, i.e. {Amplitude: true}.

havePreferencesChanged

Type: boolean Default: false

A boolean value representing whether or not the user has changed their preferences since opening the preferences modal. Will be set to true if the user interacts with the preferences modal by selecting "Yes" or "No" on any of the consent categories.

This is used to not reload the page if no preferences have changed, as to not create a disruptive user experience.

isConsentRequired

Type: boolean Default: true

The result of shouldRequireConsent.

workspaceAddedNewDestinations

Type: boolean Default: false

A boolean value representing whether or not there have been new destinations connected to the source(s) managed by Consent Manager, compared to the destinations set on the existing cookie.

setPreferences

Type: function(object|boolean)

Sets a preference to a new value in state. By default it takes an object map in the format of {destinationId: true|false}, but if you're using mapCustomPreferences the object map can be in any format you want. It behaves like setState() in that you can set one or more preferences at a time and they get merged with what's currently in state. You can also pass a boolean to set all destination preferences to true or false (you shouldn't do this if you're using mapCustomPreferences).

resetPreferences

Type: function

Resets the preferences state to the value saved in the cookie. Useful for resetting the state when the preferences dialog is closed without saving for example.

saveConsent

Type: function(object|boolean)

Saves the preferences currently in state to a cookie called tracking-preferences, triggers an identify call with destinationTrackingPreferences and customTrackingPreferences traits and then reloads analytics.js using the new preferences. It can also be passed preferences like setPreferences to do a final update before saving.

onError

Type: function(object)

Allows you to manually handle if there is an error when initializing - e.g. if there is an ad blocker that prevented fetching the destinations. This will prevent an uncaught error e.g. Failed to fetch.

Utility functions

  • openConsentManager() - Opens the ConsentManager preferences dialog.
  • doNotTrack() - Returns the user's Do Not Track preference (normalises the cross browser API differences). Returns true, false or null (no preference specified).

Setting Custom Anonymous ID

Analytics.js generates a universally unique ID (UUID) for the viewer during the library’s initialization phase, and sets this as anonymousId for each new visitor to your site. This happens before Analytics.js loads any device-mode destinations, and so before these destination-libraries can generate their own user IDs.

Example

ajs_anonymous_id=%2239ee7ea5-b6d8-4174-b612-04e1ef3fa952

You can override the default-generated anonymousID from the Segment snippet.

analytics.SNIPPET_VERSION = '4.13.2'
analytics.page()
analytics.setAnonymousId('YOUR_CUSTOM_ID')

Note: Keep in mind that setting the anonymousId in Analytics.js does not overwrite the anonymous tracking IDs for any destinations you’re using.

There are other ways to override the anonymousID, you can find more information here.

Development

To run our storybook locally, simply do:

$ yarn dev

and the storybook should be opened in your browser. We recommend adding a new story for new features, and testing against existing stories when making bug fixes.

Publishing New Version

This package follows semantic versioning. To publish a new version:

$ npm version <new-version>
$ npm publish

License

consent-manager is released under the MIT license.

Copyright © 2021, Segment.io, Inc.