Skip to main content

CCM19

This document provides the required information for integrating CCM19 CMP and Contentpass. Please complete the following general steps first

General Tasks

Here, all general tasks are listed. Contentpass does not directly obtain or store any user consent, or any other personal data for that matter. We have integrations with several Consent Management Providers though. Everything CMP-specific is described in the according sub-pages.

Steps:

  1. Make sure no third party resources are loaded without consent
  2. Sign up for a Contentpass account
  3. Configure CNAME Record for Contentpass Session Management
  4. Mention Contentpass in Privacy Policy
  5. Integrate Contentpass with your CMP
  6. Further improvements

To prevent leaking user data to third parties, it's obligatory that those are only loaded after the user consented. Please refer to our page on Third Party Resources for details on why this is an issue.

Important

Before you begin this section please check the CCM19 dashboard to ensure that you have configured all of the integrations and vendors (CCM19 refers to them as "Providers") used on your website.

CCM19 provides various methods to integrate third-paries. Only "Integration type 3", where the script tags are being rewritten, enables you and Contentpass to offer guaruanteed ad- and tracking-free access.

For IAB vendors you could instead also use the TCF API to load vendors after they have received consent. You can find a code example here.

Below we have included an example of how to block third party resources loaded via scripts on your page, using the methods and examples provided by CCM19. In all examples the "example-group" must be replaced with the value of the the group you created for the respective vendor(s) in CCM19.

External Resource example:

<!-- Before Modification -->
<script src="https://third-party-resource.net/script.js" type="text/javascript"></script>

<!-- After Modification -->
<script
data-ccm-loader-src="https://third-party-resource.net/script.js"
type="text/x-ccm-loader"
data-ccm-loader-group="example-group"
></script>

Inline Resource example:

<!-- Before Modification -->
<script type="text/javascript">
// some code that loads a third party
</script>

<!-- After Modification -->
<script type="text/x-ccm-loader" data-ccm-loader-group="example-group">
// some code that loads a third party or is only needed when a specific third-party has consent
</script>

Iframe/Embed Blocking

To prevent loading of third-party resources prior to consent it is obligatory that you set up the vendor and embed code accordingly.

First, you will need to ensure that all the embeddings have a value set in the "group for the script loader" field of the "Embeddings & Cookies" section of the CCM19 dashboard, read here for more information.

Now you just need to modify your iframe code by replacing the src and adding the new data-ccm-loader-group attribute with the value of the loader group name for this embedding.

note

In order for the activation via the embeddings to work, you must activate the iframe blocker via "Iframes > Activate iframe blocking" in CCM19.

Here's a real world example of what this would look like for blocking a YouTube embed iframe with the methods provided by your CMP.

Before:

<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/o-YBDTqX_ZU?si=kIXigqia0y1qbUpX"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
>
</iframe>

After:

<iframe
width="560"
height="315"
data-ccm-loader-src="https://www.youtube-nocookie.com/embed/o-YBDTqX_ZU?si=kIXigqia0y1qbUpX"
data-ccm-loader-group="example-group-youtube"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
>
</iframe>

This will ensure that no requests will be sent to the third-party until after the user has given consent to the example-group-youtube. For unconsented impressions CCM19 will automatically display a button that allows the user to consent to the embed's vendor.

YouTube embeds

Please note, that in above example also the domain for YouTube has been changed from youtube.com to youtube-nocookie.com. For regular embeds YouTube loads Doubleclick by default and shows data-driven advertising. Please always use YouTube's "Enhanced Privacy Mode" by using the youtube-nocookie.com domain for all their embeds.

For more information on embedding content safely you can also refer to the documentation of CCM19 on embeds.

info

Visit our docs on Third Party Resources for more information on how to block third parties and the technical details on why this is important.

1. Sign up for Contentpass

Go to publisher.contentpass.net and create your publisher account. The wizard will guide you through the steps of creating a publisher profile as well as the first property. The property's status page will present the required steps for a successful Contentpass integration. This document contains further details that should help you with the process.

2. Configure CNAME Record for Contentpass Session Management

Since 3rd-party cookies don't work reliably anymore in most browsers, Contentpass subscribers must be identified using a 1st-party session.

To simplify handling of these 1st-party sessions, Contentpass provides an endpoint that must be configured behind a CNAME subdomain of the publisher's first-party domain.

In the following example we assume that the publisher's website is: https://www.example.com and the propertyId is 1234abcd. You can find your propertyId in the settings of your property. Can't find it? Get in touch with us to obtain your propertyId.

A CNAME must be set up as follows:

cp.example.com. 300 IN CNAME 1234abcd.12.with.contentpass.net.

Once the CNAME has been set up, Contentpass will automatically provision the required SSL certificates.

3. Mention Contentpass in Privacy Policy

While we do not process any data of non-subscribers, we receive the IP addresses of your visitors for technical reasons. Please inform your visitors about this data processing and link to our privacy policy by including the following snippet on your privacy policy page:

Contentpass

Auf unserer Website bieten wir Ihnen einen Service zum werbe- und tracking-freien Zugang an. Dieser Service nennt sich Contentpass und ist ein Angebot der Content Pass GmbH, Wolfswerder 58, 14532 Kleinmachnow, Deutschland. Beim Abschluss des Service wird Contentpass Ihr Vertragspartner. Weitere Informationen zu diesem Service finden Sie auf contentpass.net.

Um Ihnen diesen Service auf unserer Website anzuzeigen und damit anbieten zu können, verarbeitet Contentpass, in unserem Auftrag, mit dem Besuch unserer Website Ihre IP-Adresse. Für die Registrierung sowie die Vertragsabwicklung des Contentpass und die damit einhergehende Datenverarbeitung ist Contentpass Verantwortlicher im Sinne der DSGVO. Wir sind ausschließlich Verantwortlicher für die Verarbeitung Ihrer IP-Adresse. Für weitere Informationen bezüglich der Datenverarbeitung bei Contentpass lesen Sie bitte die dortigen Datenschutzhinweise.

Grundlage für die Datenverarbeitung der IP-Adresse, im Rahmen unserer Auftragsverarbeitung mit Contentpass, ist unser berechtigtes Interesse Ihnen die Möglichkeit zu bieten, unsere Website werbe- und tracking-frei aufrufen zu können und Ihr Interesse an der Nutzung unserer Website praktisch ohne Werbung und Tracking [Art. 6 Abs. 1 lit. f) DSGVO]. Zudem erfüllen wir hiermit die rechtliche Verpflichtung, eine rechtskonforme Einwilligung in einwilligungsbedürftige Datenverarbeitungen einzuholen [Art. 6 Abs. 1 lit. c) DSGVO].

Sie können sich hier in Ihr Contentpass-Konto einloggen, und sich hier für Contentpass anmelden.

Note:

Link target for login:

javascript: cp('login');

Link target for signup:

javascript: cp('signup');
tip

Since these are not quite ordinary links, it may happen that your CMS does not support them. In that case, you can simply link to https://www.contentpass.net/login and https://www.contentpass.net/signup instead.


4. CCM19 Contentpass integration

This guide assumes you are visiting the English language version of the CCM19 dashboard

Before integrating your CMP with Contentpass, you must configure specific settings for your site on the CCM19 dashboard.

4.1. Enable IAB TCF API

First of all you must ensure that the IAB framework TCF support option is activated. All you need to do is visit the "IAB Framework (TCFv2)" page on your domain dashboard and make sure the "Activate now" option in the "IAB framework support" section is enabled (it is usually enabled by default).

4.2. Enable Ad- and Tracking-Free Network (complete this step last!)

IMPORTANT:
Activating this setting will disable the CMP from displaying the first layer (CCM19's widget). This is because the CMP will assume that the consent layer is being handled by the ad- and tracking-free network i.e Contentpass. This is the desired behaviour. Please only activate this option when all other onboarding steps are complete and your property is ready to go live.

Instructions:

In order for our SDK to connect with CCM19's code you must enable the "My website is part of an ad- and tracking-free network" option in the Developer settings/Frontend behavior section for your domain.

Here we will demonstrate how to turn this setting on in the CCM19 Dashboard:

Find Your Domain Dashboard

First you will need to visit the dashboard page for your site aka domain

Locate The Developer Settings

At the very bottom of the left-side navbar (you might need to scroll) there is an option for Developer Settings (Developer-Einstellungen in German), click this

Turn On Required Frontend Setting and save

At the top of this page there is a section of settings called "Frontend Behaviour" ("Frontend-Verhalten" in German). The setting required to integrate CCM19 with Contentpass is called "My website is part of an ad and tracking-free network" ("Meine Website ist Teil eines werbe- und trackingfreien Netzwerks" in German). This option is turned off by default. This must be switched to on.

Then click the "Save" button at the bottom of the screen to save this setting and you are done!



Once this setting is turned on you can now integrate your CMP with Contentpass. Please double-check that IAB Framework Support is turned on.

Add Contentpass snippet

After integrating the script in the head section of your website, Contentpass will render the consent layer including the Contentpass offering.

Warning

Please make sure that the Contentpass script is loaded before the CCM19 script (https://cloud.ccm19.de/app.js) and does not contain any parameters that might delay the loading of the script.


<script type="text/javascript" charset="UTF-8">
!function() {
var cpBaseUrl = 'https://cp.example.com';
var cpController = cpBaseUrl + '/now.js';
var cpPropertyId = '1234abcd';

!function(C,o,n,t,e,P,a,s){C.CPObject=n,C[n]||(C[n]=function(){
for(var i=arguments.length,c=new Array(i),r=0;r<i;r++)c[r]=arguments[r];var f=c[0],u=c[1],l=c[2];if(C[n].q||(C[n].q=[]),
e=Array.prototype.slice.call(arguments,0),!C[n].patched)if("fatal"===f&&u)C[n].le=u,
Array.prototype.forEach.call(C[n].q,(function(e){"error"===e[0]&&"function"==typeof e[1]&&e[1](u)
}));else if("error"===f&&"function"==typeof u)C[n].le&&u(C[n].le);else if("extension"===f&&u)l&&"function"==typeof l.init&&(l.init(),
l.initialized=!0);else if("authenticate"===f&&"function"==typeof u){try{
P=-1===(o.cookie||"").indexOf("_cpauthhint=")&&!(C.localStorage||{})._cpuser&&-1===C.location.href.toLowerCase().indexOf("cpauthenticated")
}catch(e){P=!1}if(P){a={isLoggedIn:function(){return!1},hasValidSubscription:function(){return!1}}
;var p=u,d=!1,h=function(e,i){d||(d=!0,p(e,i))};if(e[1]=h,"function"==typeof o.hasPrivateToken)try{
o.hasPrivateToken(t||"https://my.contentpass.net").then((function(e){e||h(null,a)})).catch((function(){}))
}catch(e){}else h(null,a)}}C[n].q.push(e)});try{
((s=(o.cookie.split("_cpauthhint=")[1]||"").split(";")[0])?Number(s[1]):NaN)>0&&(o.body?o.body.classList.add("cpauthenticated"):o.addEventListener("DOMContentLoaded",(function(){
o.body.classList.add("cpauthenticated")})))}catch(e){}C[n].l=+new Date,C[n].sv=6}(window,document,"cp");

// Will activate Contentpass and initialize basic interfaces for
// communicating with Contentpass
cp('create', cpPropertyId, {
baseUrl: cpBaseUrl
});

// Will render the layer provided by contentpass.
// If user gives full consent, the onFullConsent callback is fired.
// If user is logged into contentpass and has a valid subscription for the
// current website, no layer is displayed.
// Use the cp('authenticate') function below to react on further details
// regarding contentpass users.
cp('render', {
onFullConsent: function() {
console.log('[CP] onFullConsent');
// load advertising
}
});

// Will evaluate the user's login state regarding contentpass and whether
// user has a valid subscription.
// This call is optional as cp('render') above is also checking for the
// contentpass subscription state.
// Use this function for example to update your layout for contentpass users.
// We also provide CSS-based and cookie-based options for this case.
cp('authenticate', function (error, user) {
if (error) {
// Error handling depending on use case
return;
}

if (user.isLoggedIn() && user.hasValidSubscription()) {
// User has valid subscription
} else {
// User has no valid subscription
}
});
}()
</script>
<script src="https://cp.example.com/now.js" async fetchPriority="high" onerror="cp('fatal', arguments)"></script>
<script src="https://cloud.ccm19.de/app.js?apiKey={{apiKey}}&amp;domain=undefined" referrerpolicy="origin"></script>

Keeping Contentpass code snippet up to date

We’re always aiming to improve the Contentpass code snippet to ensure optimal performance, compatibility, and functionality. Sometimes also updates of our CMP partners require an update of our integration, and thus your code that initializes the CMP and Contentpass.

To save effort on your end, we want to keep the amount of updates low, but on the other hand those updates should never be breaking changes. But of course it's always beneficial to use the latest version.

How to know when an update is needed

We check your integration with our daily property reviews. The property status page in your publisher dashboard will either show a green, yellow or red status. For yellow, we strongly recommend to update, but it's not urgent. In case you landed here because the code snippet check turned red, or you got the corresponding mail notification, please immediately update the Contentpass code snippet.

How to update the Contentpass code snippet

Simply replace the outdated snippet with the latest version. You’ll always find the latest version in the above section: Add Contentpass snippet.

4.3 Allow the user to open the CMP settings

To open the CMP settings layer, CCM19 provides a simple SDK function: CCM.openWidget()

You can easily trigger this function by adding a link to your footer with an onclick handler like this:

<a href="#" onclick="CCM.openWidget();return false;">Open Consent Settings</a>
Please read CCM19's documentation for more in-depth instructions.

5. Further Improvements

5.1 Performance Optimizations (optional)

Providing a reliable and high-performant service is one of our highest concerns. One such way is by ensuring our now.js bundle is as small as possible (~30 KB) and also having our components loaded asynchronously, so chunks are fetched only as needed.

Speed up connection to our servers

One way in which you can improve the initial loading time of your page is by adding a preconnect link element to the head of your website. This will tell the browser to initiate a connection to our servers as early as possible so it is ready when our actual SDK is requested.

warning

The following snippet contains a placeholder value that you need to replace with the correct value for your property

  • The href placeholder https://cp.example.com should use the CNAME created for your property. You can find the correct values for the property on the publisher dashboard.


You can find the correct values for your property on the Publisher Dashboard

Please replace the href placeholder and add the following tag to the head of your page, as high up in the HTML as possible.

<link rel="preconnect" href="https://cp.example.com" />

You can also initiate a preconnect via the Link HTTP header

loading the SDK

Additionally, incorporating the fetchPriority attribute in our SDK script tag, setting its value to "high", and placing it high up inside the element of the HTML can significantly enhance the page's response time. This is because the browser can immediately fetch the resources it needs to render the first layer.

Faster Loading

In some rare situations you may want to load third-parties without basing it on TCF-Consent, but not load them for Contentpass users. There is a way to accomplish this without relying on our backend, thus without additional request. Please consult our Loading third-parties for non-subscribers only section in the third-party docs for details.

5.2 Improving UX for Contentpass users

We offer a few methods for you to recognize if the current visitor is a Contentpass subscriber, so you can improve the user experience for them. This can be achieved on both the client and server side.

Client-Side Javascript

To check if a Contentpass subscriber is authenticated on the front-end we recommend using our SDK method: cp('authenticate'), see our web-sdk docs for more details. The callback argument will return an object that contains all the up-to-date information you need to determine a user with a valid Contentpass session.

cp('authenticate', function (error, user) {
if (error) {
// Error handling depending on use case
return;
}

if (user.isLoggedIn() && user.hasValidSubscription()) {
// User has valid subscription
} else {
// User has no valid subscription
}
});

The .cpauthenticated CSS class

Improving User Experience

To avoid having lots of empty ad-slots for Contentpass users, we provide a way to recognize Contentpass users on the client-side via CSS.

We provide a special css selector cpauthenticated which allows you to easily change the page styling depending on the user's authentication status. When an authenticated user is logged-in the class name cpauthenticated is added to the class list of the body tag.

This provides you with the means to easily customise any child elements without having to check the subscription status yourself.

info

Please ensure that this CSS rule is applied as early as possible on your page to avoid layout shifts of the page content! Adding it to the first CSS file that is loaded on your page is recommended, or as high up as possible in the <head> of your page.

Examples

Basic example: hiding all containers with a specific class for authenticated users

This basic css can be added to your stylesheet to hide all containers with the class ad-container as soon as the user is logged in with Contentpass

body.cpauthenticated .ad-container {
display: none;
}
Advanced example: hiding containers which have anchor tags with a specific href

This example shows how to hide all containers with the class ads which contain an anchor tag with an href starts with http and that does not contain example.com/. This is useful to e.g. hide all external ads that are not from your own domain while e.g. still showing internal sponsored articles.

<html lang="en">
<head>
<style>
body.cpauthenticated
.ads:has(a[href^="http"]:not([href*="example.com/"])) {
display: none;
}
</style>
</head>

<body class="cpauthenticated">
<div class="ads">
<p>adserver.com</p>
<a href="https://adserver.com/?redirect=123">
<img src="..." />
</a>
</div>

<div class="ads">
<p>example.com</p>
<a href="https://example.com/mysponsoredarticle.html">
<img src="..." />
</a>
</div>
</body>
</html>

Conclusion

The cpauthenticated class provides developers with a convenient way to manage user authentication states and dynamically adjust the display of elements within their web applications. By leveraging the cpauthenticated class, developers can create a more personalized and seamless user experience for their audience.

warning

We do not recommend relying on this as a robust method for recognizing Contentpass users for business logic. CSS classes can be easily manipulated by the user or any other javascript running on the page. Additionally there is no guarantee that the CSS styles are applied before your javascript runs.

For recognizing Contentpass users on the backend we provide a _cpauthhint cookie that we set on the user's browser. If the user is a logged-in Contentpass user the cookie will have a value of 1 and 0 if they are logged out.

The following is a simplified-code example of how one might check for the cookie on a node.js server, in order to serve content without anti-adblocking messages for Contentpass users and only for regular users.

// Middleware to check the "_cpauthhint" cookie
function checkUserType(req, res, next) {
const cpAuthHintCookie = req.cookies._cpauthhint;

// Check if the cookie exists and has the value for a logged in CP user
req.isLoggedInCpUser = cpAuthHintCookie === '1';

next();
}

// Route that uses the authentication middleware
app.get('/dashboard', checkUserType, function (req, res) {
// Render different views for ContentPass users and regular users
if (req.isCpUser) {
res.render('dashboard', { user: 'ContentPassUser', showAdblockCommunication: false });
} else {
res.render('dashboard', { user: 'RegularUser', showAdblockCommunication: true });
}
});