@schibsted/sourcepoint
v6.0.5
Published
Package containing scripts used by Schibsteds' sites to integrate with Sourcepoint CMP
Readme
CMP products - Javascript SDK
This repository contains a small library to simplify the implementation of popup-ups delivered by Sourcepoint.
Don't hesitate to contact us on our Slack channel: #consent-management-support.
Integrations
- PSI (Privacy Settings Introducer)
- SCC (Schibsted Cookie Consent)
- TCF (Transparency & Consent Framework)
Config
Configuration for your implementation can be found in the CMP_Configuration_setup.
| Required parameters | Description |
| ------------------------- | ----------------------------------------------------------------------------------------------------------- |
| propertyId: number | Maps the message to a specific property (website, app, OTT) as set up in the Sourcepoint account dashboard. |
| consentLanguage: string | Consent message language. Available: en, no, sv, fi, dk. |
| baseEndpoint: string | A single server endpoint that serves the messaging experience. |
| groupPmId: number | SCC and TCF only. Allows to use the Privacy Manager ID. |
| Optional parameters | Description |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| accountId: number | Used to override organization's Sourcepoint account. Default value:1047 |
| propertyHref: string | Used to display a message from one property, e.g. production url, on another domain, e.g. staging/test site. |
| targetingParams: array<string> | Array with key value pairs passed to Sourcepoint - could be used as conditions in scenarios. |
| userId: number | The Schibsted account user identifier for the logged in user. E.g. 123456, not full SDRN. Send only if user is logged in. More info below. |
| realm: string | The Schibsted account realm of the logged in user. E.g. schibsted.com, spid.no, schibsted.fi. More info below. |
| clientId: string | Provide in order to redirect user to Privacy Settings page with client_id parameter. It's a unique identifier generated for an individual service client. |
| pulseTracker: object | Pulse Event Tracker object. More details here. Only in the client-side integration. |
| referrer: string | Used to allow users to return to the exact page from Privacy Settings UI. Its default value is the current URL. |
| state: string | It should be a base64-encoded string. Enables passing any query parameters as a part of a specific redirect URL. More details in Privacy Settings docs. |
| pulseObjectName: string | Provide when you assign Pulse to different variable than window.pulse. Used in the server-side integration type. |
| showInWebview: string | DEPRECATED. This option is ignored. The SDK always sets targetingParams['mobile-webview'] = true when a webview is detected. |
| identityObject: object | Schibsted Account Identity object. More details here. |
| identityObjectName: string | Provide in case you assigned the Identity object to a different global variable than window.Identity. |
| enableUserCentric: boolean | Enables the brand level consent feature. The user's consent is attached to the authId and will be stored on the backend. |
| enableEcosystemConsent: boolean | DEPRECATED. This feature has been removed and is no longer supported. The option will be ignored if provided. |
| groupId: string | Extension of the enableUserCentric parameter: to handle more specific cases. Provide if consent shouldn't be tied to the merchant level. |
| disableNativeConsentCheck: boolean | Disable blocking of CMP snippet on webviews that don't provide _sp_pass_consent parameter in URL |
| disableSentry: boolean | Disables the Sentry error tracking. |
| enableAdChoicesFeature: boolean | Enables Ad Choices feature for TCF. Only users with specific subscription will have all consents rejected and targeting parameter enableAdChoices=true set. |
| adChoicesProductId: string | Product ID used to check subscription for Ad Choices. Default value: NOCON |
| adChoicesSubscriberPmId: number | When provided, the SDK selects this Privacy Manager ID for AdChoices subscribers |
Installation
Install package from NPM using command:
// npm
npm install @schibsted/sourcepoint
// yarn
yarn add @schibsted/sourcepointPrivacy Settings Introducer (PSI)
The PSI is used to identify Schibsted as the data controller and alert users about choices available to them in Privacy Settings, along with a link to get there.
Browser integration
import { psi } from '@schibsted/sourcepoint';
psi(window, document, navigator, {
baseEndpoint: 'https://cmp.YOUR_DOMAIN/', // required
propertyId: 1234, // required
consentLanguage: 'sv', // required
userId: 123456,
realm: 'spid.no',
});NodeJS integration
const { psi } = require('@schibsted/sourcepoint');
const snippet = psi({
baseEndpoint: 'https://cmp.YOUR_DOMAIN/', // required
propertyId: 1234, // required
consentLanguage: 'sv', // required
userId: 123456,
realm: 'spid.no',
});
// Now you can add the snippet to the page:
// index.js
// app.get('/', (req, res) => res.render('page', { snippet }));
// page.hbs
// <html><head>{{snippet}}</hread><body>...</body></html>Note: Both SCC and TCF integrations include support for PSI. This means that if you call scc or tcf snippet, don't call psi as part of the same integration.
PSI for logged in users only
If you are using the TCF integration, PSI will most likely only be visible to logged in users. There are 2 ways to achieve this:
Provide
userIdto the initial config. The user state must be provided with the initialisation of the tcf snippet, so you'll have to delay the initialisation of the snippet until there is a response from the Schibsted Account SDK.Use the Brand Level Consent feature. With this feature we can retrieve and set the
userIdourselves.
Schibsted Cookie Consent (SCC)
Privacy Settings Introducer (PSI) is a part of Schibsted Cookie Consent integration. If your site is already integrated with PSI you need to remove existing integration (or do required changes).
Step 1: Add Sourcepoint Client Configuration Code Snippet
Browser integration
import { scc } from '@schibsted/sourcepoint';
scc(window, document, navigator, {
baseEndpoint: 'https://cmp.YOUR_DOMAIN/', // required
propertyId: 1234, // required
consentLanguage: 'sv', // required
groupPmId: 1234, // required
userId: 123456,
realm: 'spid.no',
});NodeJS integration
const { scc } = require('@schibsted/sourcepoint');
const snippet = scc({
baseEndpoint: 'https://cmp.YOUR_DOMAIN/', // required
propertyId: 1234, // required
consentLanguage: 'sv', // required
groupPmId: 1234, // required
userId: 123456,
realm: 'spid.no',
});
// Now you can add the snippet to the page:
// index.js
// app.get('/', (req, res) => res.render('page', { snippet }));
// page.hbs
// <html><head>{{snippet}}</hread><body>...</body></html>Step 2: SCC integration with the site
In step 1 you have added required code to present user SCC and ask him about consents.
In second step you need to integrate your site with SCC Library to honour user choices.
Cookies (scripts) could belong to one of these categories:
Essential- Necessary cookies which could be set always, without asking user about the consent (this category is not supported by the library because consent is not required).CMP:advertising- Advertising related Cookies - user consent is required.CMP:analytics- Analytics and Product Development related cookies - user consent is required.CMP:marketing- Marketing related Cookies - user consent is required.CMP:personalisation- Personalisation related Cookies - user consent is required.
Your site could run script only when consent was given by user.
To receive information about user choices you can use one of two provided methods:
getPermission- allows getting information about consent once (asynchronous)getPermissionSync- allows getting information about consent (synchronous)subscribe- allows getting information about the concent and be notified about future changessubscribeAny- allows being notified about any future changes
Library inform your site about one of two states (PermissionValue):
"1"- cookies could be set / script could be run - user gave consent"0"- cookies could NOT be set / script could NOT be run - user hasn't given consentnull- user hasn't made a decision yet (returned only by synchronous function)
Returned values are cached in LocalStorage to speed up integration.
Allow reopening Privacy Manager
To allow users change their choices each page should contain a link to re trigger Schibsted Cookie Consent.
Function: window._scc_.showPrivacyManager() allows reopening Privacy Manager.
Schibsted Cookie Consent Interface
getPermission
Function window._scc_.getPermission allows getting information about consent once:
window._scc_.getPermission(category: Categories, callback: (value: PermissionValue) => {})Categories:
CMP:advertising- Advertising related CookiesCMP:analytics- Analytics and Product Development related cookiesCMP:marketing- Marketing related CookiesCMP:personalisation- Personalisation related Cookies
PermissionValue:
"1"- cookies could be set"0"- cookies could NOT be set
getPermissionSync
Function window._scc_.getPermissionSync allows getting information about consent once, synchronously:
window._scc_.getPermissionSync(category: Categories)Categories:
CMP:advertising- Advertising related CookiesCMP:analytics- Analytics and Product Development related cookiesCMP:marketing- Marketing related CookiesCMP:personalisation- Personalisation related Cookies
PermissionValue:
"1"- cookies could be set"0"- cookies could NOT be setnull- user hasn't made a decision yet
subscribe
Function window._scc_.subscribe allows getting information about the concent and be notified about future changes.
const unsubscribeFn = window._scc_.subscribe(category: Categories, callback: (value: PermissionValue) => {}): () => voidCategories:
CMP:advertising- Advertising related CookiesCMP:analytics- Analytics and Product Development related cookiesCMP:marketing- Marketing related CookiesCMP:personalisation- Personalisation related Cookies
PermissionValue:
"1"- cookies could be set"0"- cookies could NOT be set
Returned value is a function which allow unsubscribing from notification about changes.
subscribeAny
Function window._tcf_.subscribeAny allows getting notifications about any future changes to consents. Will only trigger once per set of changes.
const unsubscribeFn = window._tcf_.subscribeAny(callback: () => {}): () => voidReturned value is a function which allow unsubscribing from notification about changes.
showPrivacyManager
Function window._scc_.showPrivacyManager allows reopening Privacy Manager - thanks to that user could change settings.
window._scc_.showPrivacyManager();This function require parameter groupPmId in the config to work properly.
Transparency & Consent Framework (TCF)
Privacy Settings Introducer (PSI) is a part of TCF integration. If your site is already integrated with PSI you need to remove existing integration (or perform the required changes).
Step 1: Add Sourcepoint Client Configuration Code Snippet
Browser integration
import { tcf } from '@schibsted/sourcepoint';
tcf(window, document, navigator, {
baseEndpoint: 'https://cmp.YOUR_DOMAIN/', // required
propertyId: 1234, // required
consentLanguage: 'sv', // required
groupPmId: 1234, // required
});NodeJS integration
const { tcf } = require('@schibsted/sourcepoint');
const snippet = tcf({
baseEndpoint: 'https://cmp.YOUR_DOMAIN/', // required
propertyId: 1234, // required
consentLanguage: 'sv', // required
groupPmId: 1234, // required
});
// Now you can add the snippet to the page:
// index.js
// app.get('/', (req, res) => res.render('page', { snippet }));
// page.hbs
// <html><head>{{snippet}}</hread><body>...</body></html>Step 2: TCF integration with the site
In step 1 you have added required code to present user TCF and ask him about consents.
In second step you need to integrate your site with TCF Library to honour user choices.
Cookies (scripts) could belong to one of these categories:
Essential- Necessary cookies which could be set always, without asking user about the consent (this category is not supported by the library because consent is note required).CMP:advertising- Advertising related Cookies - user consent is required.CMP:analytics- Analytics and Product Development related cookies - user consent is required.CMP:marketing- Marketing related Cookies - user consent is required.CMP:personalisation- Personalisation related Cookies - user consent is required.CMP:performance_marketing- Only used where there is a waiver from Privacy Legal to run marketing campaigns on third party platforms, and where consent forCMP:marketingdoes not apply.
Your site could run script only when consent was given by user.
To receive information about user choices you can use one of two provided methods:
getPermission- allows getting information about consent once (asynchronous)getPermissionSync- allows getting information about consent (synchronous)subscribe- allows getting information about the concent and be notified about future changessubscribeAny- allows being notified about any future changes
Library inform your site about one of two states (PermissionValue):
"1"- cookies could be set / script could be run - user gave consent"0"- cookies could NOT be set / script could NOT be run - user hasn't given consentnull- user hasn't made a decision yet (returned only by synchronous function)
Returned values are cached in LocalStorage to speed up integration.
Step 3: Allow reopening Privacy Manager
To allow users to change their choices, each page should contain a link to re-trigger TCF.
Function: window._tcf_.showPrivacyManager allows reopening Privacy Manager.
Methods
getPermission
Function window._tcf_.getPermission allows getting information about consent once:
window._tcf_.getPermission(category: Categories, callback: (value: PermissionValue) => {})Categories:
CMP:advertising- Advertising related CookiesCMP:analytics- Analytics and Product Development related cookiesCMP:marketing- Marketing related CookiesCMP:personalisation- Personalisation related CookiesCMP:performance_marketing- Marketing campaigns on third party platforms related Cookies
PermissionValue:
"1"- cookies could be set"0"- cookies could NOT be set
getPermissionSync
Function window._tcf_.getPermissionSync allows getting information about consent once, synchronously:
window._tcf_.getPermissionSync(category: Categories)Categories:
CMP:advertising- Advertising related CookiesCMP:analytics- Analytics and Product Development related cookiesCMP:marketing- Marketing related CookiesCMP:personalisation- Personalisation related CookiesCMP:performance_marketing- Marketing campaigns on third party platforms related Cookies
PermissionValue:
"1"- cookies could be set"0"- cookies could NOT be setnull- user hasn't made a decision yet
subscribe
Function window._tcf_.subscribe allows getting information about the concent and be notified about future changes.
window._tcf_.subscribe(category: Categories, callback: (value: PermissionValue) => {}): () => voidCategories:
CMP:advertising- Advertising related CookiesCMP:analytics- Analytics and Product Development related cookiesCMP:marketing- Marketing related CookiesCMP:personalisation- Personalisation related CookiesCMP:performance_marketing- Marketing campaigns on third party platforms related Cookies
PermissionValue:
"1"- cookies could be set"0"- cookies could NOT be set
Returned value is a function which allow unsubscribing from notification about changes.
subscribeAny
Function window._tcf_.subscribeAny allows getting notifications about any future changes to consents. Will only trigger once per set of changes.
const unsubscribeFn = window._tcf_.subscribeAny(callback: () => {}): () => voidReturned value is a function which allow unsubscribing from notification about changes.
showPrivacyManager
Function window._tcf_.showPrivacyManager allows reopening Privacy Manager - thanks to that user could change settings.
window._tcf_.showPrivacyManager();This function require parameter groupPmId in the config to work properly.
isConsentedToAll
Function window._tcf_.isConsentedToAll allows getting information about whether user consented to all purposes and be notified about future changes.
window._tcf_.isConsentedToAll(callback: (value: boolean) => {}): () => voidgetConsentedToAllSync
Function window._tcf_.getConsentedToAllSync allows getting information about consentedAll status once (instead of reacting on consent change), based on the data retrieved from browser's local storage.
window._tcf_.getConsentedToAllSync();Function returns boolean | null.
Ad Choices
If you enable Ad Choices (enableAdChoicesFeature: true), the SDK will automatically check if the user has access to specific subscription and if so, it will reject all TCF consents and set the enableAdChoices=true targeting parameter.
Important Note for Custom Snippet Integrations:
The TCF snippet performs an asynchronous check for Ad Choices. If you are loading the Sourcepoint messaging script separately (not using the built-in tcf-with-messaging.js template), you must wait for the AdChoices flow to complete:
// Wait for AdChoices check to finish
window.__sp_tcf_ready.then(() => {
// Load messaging script here
const script = document.createElement('script');
script.src = `https://cmp.YOUR_DOMAIN/unified/wrapperMessagingWithoutDetection.js`;
document.head.appendChild(script);
});Core features
Pulse SDK integration
PSI, SCC and TCF are integrated with Pulse and we ask you to allow us to collect user and device data.
If you use the Pulse SDK, please add a tracker object to the config or assign it to the window. With the Pulse Autotracker (deprecated), you will have a global pulse method which is not available when following the SDK way.
Minimum Pulse version required:
- SDK:
5.0.0 - Autotracker:
2.0.0
Browser integration
Provide pulseTracker to the config:
pulseTracker: new Tracker('{CLIENT-ID}', {}, {})In the case of SCC and TCF integrations, it is required to provide a consents object to the initial Pulse config. You can use the method getCachedOrDefaultConsentsForPulse for that purpose.
- If you use SDK integration
TCF
const consents = window._tcf_.getCachedOrDefaultConsentsForPulse();
const tracker = new Tracker('{CLIENT-ID}', {
consents,
requireAdvertisingOptIn: true,
});
window.pulse = (callback) => callback(tracker);SCC
const consents = window._scc_.getCachedOrDefaultConsentsForPulse();
const tracker = new Tracker('{CLIENT-ID}', {
consents,
requireAdvertisingOptIn: true,
});
window.pulse = (callback) => callback(tracker);- If you use Autotracker integration
TCF
const consents = window._tcf_.getCachedOrDefaultConsentsForPulse();
pulse('init', 'CLIENT-ID', {
consents,
requireAdvertisingOptIn: true,
});SCC
const consents = window._scc_.getCachedOrDefaultConsentsForPulse();
pulse('init', 'CLIENT-ID', {
consents,
requireAdvertisingOptIn: true,
});Server integrations
Assign Pulse tracker to the global window object:
window.pulse = (callback) => callback(pulseTracker)*If you want to assign Pulse to any other variable - you can but you have to also provide pulseObjectName to the config.
window.whatever = (callback) => callback(pulseTracker)
psi(window, document, navigator, {
pulseObjectName: 'whatever'
});getCachedOrDefaultConsentsForPulse
Function window._scc_.getCachedOrDefaultConsentsForPulse(arg?) returns updated consents object for Pulse purposes. It accepts a default object in the shape of ConsentsInput as its only parameter.
TCF
const consents = window._tcf_.getCachedOrDefaultConsentsForPulse();
const tracker = new Tracker('{CLIENT-ID}', {
consents,
requireAdvertisingOptIn: true,
});SCC
const consents = window._scc_.getCachedOrDefaultConsentsForPulse();
const tracker = new Tracker('{CLIENT-ID}', {
consents,
requireAdvertisingOptIn: true,
});Examples below are also applicable in TCF integration. All you need to do is to call tcf instead of scc.
Brand Level Consent
Authenticated consent allows to share an end-user's consent preferences across their different authenticated (logged-in) devices. It can be applied to all properties within a brand, reducing the number of times users have to go through the popup flow. This feature is currently only available to logged in users.
Requirements
- Schibsted Account integration (see below)
identityobject should be assigned as a global variable (e.g.window.Identity). - The
enableUserCentricconfiguration variable must be set totrue.
Note: tcf snippet in this case is async.
import { tcf } from '@schibsted/sourcepoint';
tcf(window, document, navigator, {
baseEndpoint: 'https://cmp.YOUR_DOMAIN/',
propertyId: 1234,
consentLanguage: 'sv',
groupPmId: 1234,
enableUserCentric: true,
}).then(() => {
// content goes here
});authId is used as the consent identifier and can be found at window._sp_.config.authId.
Server-side integrations
Snippet can be attached like this:
const sourcepointSnippet = sourcepoint.tcf(sourcepointConfig, false);
<script>document.addEventListener("DOMContentLoaded", () => { ${sourcepointSnippet} })</script>then to handle any action after the setup is completed:
window._tcf_?.onTcfReady(() => {
console.log('TCF ready');
});Schibsted Account integration
In order to trigger a login flow, the SDK needs access to Schibsted Account methods. That's why in some cases we ask you to provide us with an Identity object.
The easiest way is to assign to the window:
import { Identity } from '@schibsted/account-sdk-browser';
const identity = new Identity({ ... });
window.Identity = identity;This method will work without any additional setup because that's the default solution.
If you've already assigned Identity object but to the different variable, you can help us navigate it by adding it to the config:
import { Identity } from '@schibsted/account-sdk-browser';
const identity = new Identity({ ... });
window.SPiD_Identity = identity;
import { tcf } from '@schibsted/sourcepoint';
tcf(window, document, navigator, {
identityObjectName: 'SPiD_Identity'
});You can also pass the Identity object directly to the config:
import { Identity } from '@schibsted/account-sdk-browser';
const identity = new Identity({ ... });
tcf(window, document, navigator, {
identityObject: identity
});Excluding PSI
Many mobile apps are using WebView to display web pages. By default, the snippet detects a mobile application based on the User Agent and passes this information to Sourcepoint using the window._sp_.config.targetingParams['mobile-webview'] = true attribute. The logic responsible for exclusion needs to be defined in Sourcepoint.
Devices with containing one of the string listed below are detected as mobile:
Omni_app_tv.nuFinnApp
Contact us if you want to add your app detection.
Important: showInWebview is deprecated and ignored. Use Sourcepoint scenarios to handle webview behavior.
Referrer
For some brands, PSI should not be displayed when a user is navigating between their sites, with different root domains, i.e. when a user is going from VG to Godt.
To help exclude such traffic information about hostname from document.referrer
is passed to Sourcepoint using
window._sp_.config.targetingParams['referrer-hostname'] = 'www.vg.no which allow
using String Match condition in Scenario.
Cookies
To limit number of views for brands with multiple domains support we can use additional information stored in cookies.
Example:
For document.cookie=_sch_cmp_displayed=true key-value pair will be passed:
_sch_cmp_displayed=true allowing usage of String Match condition in Scenario.
Cookie could be set using custom Javascript action for button.
Examples
You can find example PSI and SCC implementation in the folder: example.
To run it you need to clone repository and run command:
npm startExample runs on http://localhost:10001.
You can also find examples of ESI inclusion, as well as JS tag integration in these examples.
Just visit http://localhost:10001/esi.html and http://localhost:10001/js-tag.html respectively.
Testing
This package includes both unit tests and E2E (end-to-end) tests to ensure reliability.
Running Tests
# Run all tests (unit + E2E)
npm test
# Run only unit tests (fast, jsdom)
npm run test:unit
# Run only E2E tests (real browser)
npm run test:e2e
# Watch mode for development
npm run test:watchUnit Tests
Unit tests run in jsdom (simulated browser environment) and are fast. They test individual functions and components in isolation.
Location: src/**/__tests__/*.test.js
E2E Tests
E2E tests run in a real Chromium browser using Vitest Browser Mode + Playwright. These tests verify that the SDK works correctly in an actual browser environment.
Location: tests/e2e/*.browser.test.js
First time setup:
npx playwright install chromiumWhat we test:
- SDK initialization for PSI, SCC, and TCF integrations
- Event dispatching (
cmp:ready,cmp:loaded) - Window object creation (
window._sp_,window._scc_,window.__tcfapi) - Helper methods availability and functionality
- Deprecation warnings for removed features
Note: E2E tests verify the SDK's core functionality, not external API calls to Sourcepoint's servers or Schibsted's services. CORS errors in local testing are expected and do not affect test validity.
For Privacy Developers
How to publish package
Package is distributed by NPMJS.com
To publish the package you need to:
- change version in
package.jsonfile - create a tag from branch
master
Code will be published by Github Actions.
How it works
NodeJS version uses generated static scripts during publishing by rollup
(script: npm run build) - files are stored in directory: dist/.
Thanks to that code is converted to beeing compatible with old browsers, merged into one file per integration (PSI, SCC).
For debug purpose you can build files without minimization using script:
npm run build:debug,
NPM Version
NPM Version used by Github actions is defined in file .nvmrc.
This way allow you to switch to propre NodeJS version locally in an easy way too.
Running code shown below the proper NodeJS version will be used / installed.
nvm usePSI Methods:
Opening Privacy Settings
Method openPrivacySettings allows redirecting users to Privacy Settings. It enables also handling the user authentication state (being logged in or out). For non-logged-in users, there's environment_id provided as a URL parameter which means the login flow isn't triggered on the Privacy Settings page.
This method also uses client_id as a query parameter in order to display brand-specific settings and UI elements.
window.psi.openPrivacySettings(string);Example:
window.psi.openPrivacySettings('https://privacysettings.schibsted.no/');Note: This method relies on an existing Pulse integration. It means a page needs to be integrated with Pulse in order to use this method.
Pulse configuration
Events that flow into the Pulse platform via the collector needs to be routed to a destination, also called sink.
Sinks collecting data from @schibsted/sourcepoint and sending them to Amplitude are calling CMP-Amplitude-1. They can be found in two files:
Mapping Pulse data to Amplitude schema is also set in routing repo in amplitude-cmp.jstl2 file.
Pulse events
PSI is integrated with Pulse. Events are sent to your provided used by the page (using default Pulse object available on the page). You can analyse events on your own. All PSI related events are tagged using the property: provider.component = "CMP"
Privacy Services team sends events from all providers to their own project in Amplitude too.
PSI sends 2 types of events:
- View - CMP:
@type: "View",object.@type: "CMP"
Triggered when PSI or SCC is about to display to a user. - Engagement - CMP:
@type: "Engagement",object.@type: "CMP"
Triggered on user action. Actions can be distinguished in Amplitude byobject.name.
Supported PSI actions:- click on "Okay" button
- click on "To my saved preferences" button
- click on "visit out Privacy pages" link
Supported SCC actions: - click on "Accept all cookies" button
- click on "Confirm selection" button
- click on "Personal data and cookie policy" link
Schema / documentation of object.@type set to "CMP" can be found in event-formats repo.
Sourcepoint events
Documentation of Sourcepoint events can be found here.
However, working on this project we collected additional information which can be useful in development.
About onMessageReceiveData event:
- It is a normal behaviour that this event listener fires on every pageview.
- If the
messageIdin callback data is different from0, it means that the message was displayed to the user. - Event callback is not returning the
cmpgn_id(listed in documentation), because themessageIdis changing from campaign to campaign. It seems that this variable was removed from the data sent to the callback since themessageIdis already telling you which campaign it is.
About onMessageReady event:
- This event fires/triggers just before the CMP message is shown to the user. Few of Sourcepoint clients decided that they want to trigger a Privacy manager as a first layer message. Therefore, they selected in their scenario in the “Show message” event the Privacy manager layer instead of the first layer message. They use the Privacy manager as a first layer message, because they want to disclose to the user from the beginning the whole vendor list, toggles, etc.
- According to Sourcepoint team it is the best event to detect when a message is showing up to user.
Debugging
Debug messages are displayed after passing the sp_debug=1 query param.
To log out debug information, you can use the debug function from src\utils.js.
External documentation
There are external spreadsheets with useful documentation. Kind request to update it regularly :)
Links
AdChoices subscriber PM and snippet guidance
Config option:
adChoicesSubscriberPmId(number, optional) — when set, the SDK will open this Privacy Manager ID for users identified as AdChoices subscribers.Internal flag: the SDK will set
config.__sp_isAdChoicesSubscriber = truewhen the monetization check indicates the user is entitled. This flag is internal and used byshowPrivacyManager()to pick the subscriber PM when present.Snippets synchronization: generated TCF snippets expose a Promise at
window.__sp_tcf_ready. If you load messaging or other scripts that depend on TCF/snippet initialization, awaitwindow.__sp_tcf_readybefore loading them to ensure the TCF stub and AdChoices checks are initialized in the intended order.postRejectAll behavior: when the TCF stub (
__tcfapi) is present,postRejectAllis queued into the stub and the SDK processes it once the real TCF API loads. Do not rely on awaitingpostRejectAllif only the stub is available; it's intentionally non-blocking to avoid deadlocks.
