Deployment
Stand-alone or sync with backend services?
Before you start deploying it is worth considering how the CMP will operate session and UX point of view. The following will focus on stand-alone configuration and deployment for the sake of simlicity. If you are deploying with backend integration, be it Gravito CDP or your own endpoints for retrieving and storing consents from CMP, please look into specific doc about the superwrapper.js
Ok, I go for stand-alone or I have already configured superwrapper.js?
You will need wrapper.js file, edit it and deploy using e.g. with tag management system (code below is ready to be copied as-is to Google Tag Manager as custom HTML tag).
What to edit? Following is specific to service-scope use, defined to "gravitoCMPConfig" object:
Variable
Description
Release
core.settingBtnClassName
Class name for link(s) that will be used to re-open the CMP modal when user wants to review or change consent settings.
1.0.0
core.version
Indicates the version of the configuration. If the version number is changed, CMP UI will be shown again to user allowing to inform and collect new purposes, vendors etc.
1.0.0
core.allowedVendors
Defines allowed OOB vendors (only when CMP is configured to global scope)
1.0.0
core.vendors
1.0.0
core.purposes
Define purposes and/or stacks you need to enable
1.0.0
core.nonTCFVendors
If you have any, you need to maintain vendor-id mapping by yourself
1.0.0
core.customPurposes
Aka. publisher purposes. If you need consents for purposes separately.
1.0.0
core.publisherRestrictions
If you want to override some vendor-originating settings, e.g. force consent for purposes the vendor states the legitimate interest only
1.0.0
style.fonts
Set to fonts your site is using or leave as is to use gravitoFont
1.0.0
style.logoUrl
URL location of your brand logo.
1.0.0
style.primaryColor
You can set to your brand's primary color, it is used on primary buttons, link colors etc.
1.0.0
style.secondaryColor
Is used as background of cancel buttons etc., you can customize if needed.
1.0.0
core.languageCode
Two digit ISO code for the language CMP is shown
1.0.1
core.purposeOneTreatment
True or false (default), set to true only if the target market has legislative need for enabling this.
1.0.1
core.publisherCountryCode
Two digit ISO country code the publisher is residing
1.0.1
core.useTopDomain
Defaults to false, set to "true" if you want the cookie to be shared between subdomains (cookie is set to .domain.xx)
1.0.2
style.consentInputType
Defaults to checkbox, value "toggle" changes the UI
1.0.3
style.useAccordionForPurpose
Default is false, true enables accordion UI for purpose lists on 2nd layer
1.0.3
style.layoutType
Defaults to "2-tabs", "3-tabs" enables the split on UI between consents and legitimate interests
1.0.3
style.disableConfirmationModal
Default is false, "true" disables the confirmation when user turns consent off
1.0.3
core.googleTcfId
755 (avoiding to hard-code Google related settings), this enables the personalization consent check.
1.0.3
core.withBackendIntegration
true/false (default) tells the CMP whether the is superwrapper present
1.0.6
core.syncEvents
["cmpui:closed","layer1:opt-in-all"] the list of events that are sent to superwrapper, allowing it to store the consents to backend
1.0.6
style.showScrollBars
true/false, sets the scrollbar visible on 2nd layer
2.0.1
style.scrollBarWidth
if showScrollBars is set to true, this defines the width of the scrollbar, set it to e.g. "10px"
2.0.1
style.showCopyTcStringButton
true/false, enables specific icon at bottom left corner of 2nd layer, click on icon copies TCstring to clipboard for user to send it over email, chat or analyze with external tools.
2.0.3
Some texts can be altered but the content of the message cannot change, ie. CMP has been validated with following texts and changing the wording might invalidate the CMP against the TCF 2.0 policy (and cause harms to Gravito as CMP vendor).
1
<script>
2
var customCSS="";
3
var gravitoCMPConfig = {
4
core: {
5
cookieName: "TcString",
6
cookieExpiry: 365,
7
isServiceSpecific:true,
8
settingBtnClassname:"manageSettings",
9
version:1,
10
languageCode:"fi",
11
purposeOneTreatment:false,
12
publisherCountryCode:"FI",
13
googleTcfId:755,
14
withBackendIntegration: false,
15
syncEvents: ["cmpui:closed", "layer1:opt-in:all"],
16
allowedVendors:[
17
2,8,11
18
],
19
purposes: [
20
{
21
type: "purposes",
22
id: 1
23
},
24
{
25
type: "stacks",
26
id: 26
27
},
28
{
29
type: "purposes",
30
id: 10
31
}
32
],
33
specialFeatures: [
34
1, 2
35
],
36
specialPurposes: [
37
1, 2
38
],
39
features: [
40
1, 2, 3
41
],
42
vendors: [
43
2,
44
6,
45
8,
46
511,
47
11,
48
14
49
],
50
nonTCFVendors: [
51
{
52
type: "non-tcf-vendors",
53
id: 1,
54
name: "Facebook",
55
description: "Facebookin kerää tietoa verkkovierailusta ja sisällöistä myös Facebookin ulkopuolella. Facebookia käytetään mainontaan ja kerättyjä tietoja parempaan mainonnan kohdentamiseen.<br><br><a href=\"https://www.facebook.com/help/568137493302217\">https://www.facebook.com/help/568137493302217</a>",
56
isConsentable:true,
57
},
58
{
59
type: "non-tcf-vendors",
60
id: 2,
61
name: "Amazon",
62
description: "Amazonin kerää tietoja verkkovierailusta ja sisällöistä myös Amazonin ulkopuolella. Amazonia käytetään mainontaan ja kerättyjä tietoja parempaan mainonnan kohdentamiseen.",
63
isConsentable:true,
64
isLegitimate:false
65
}
66
],
67
customPurposes: [
68
{
69
type: "customPurpose",
70
id: 1,
71
name: "Tietojen keräys",
72
description: "Gravito voi kerätä tietoja verkkokäyttäytymisestä ja käyttää niitä käyttäjäkokemuksen parantamiseksi",
73
descriptionLegal: "Gravito voi kerätä tietoja verkkokäyttäytymisestä ja käyttää niitä käyttäjäkokemuksen parantamiseksi",
74
isConsentable:false,
75
isLegitimate:true
76
},
77
{
78
type: "customPurpose",
79
id: 2,
80
name: "Kohdentaminen ja personointi",
81
description: "Gravito voi käyttää tietoja sisältöjen kohdentamiseen ja personointiin",
82
descriptionLegal: "Gravito voi käyttää tietoja sisältöjen kohdentamiseen ja personointiin",
83
isConsentable:true,
84
isLegitimate:false
85
}
86
],
87
publisherRestrictions: [
88
{
89
purposeID: 1,
90
restrictionType: "REQUIRE_CONSENT",
91
vendors: [
92
6,
93
12
94
]
95
},
96
{
97
purposeID: 1,
98
restrictionType: "REQUIRE_CONSENT",
99
vendors: [
100
8
101
]
102
},
103
{
104
purposeID: 2,
105
restrictionType: "REQUIRE_CONSENT",
106
vendors: [
107
8
108
]
109
}
110
]
111
},
112
text: {
113
firstLayer: {
114
title: "Tarvitsemme suostumuksesi tarjotaksemme personoitua palvelua",
115
introductionText: "Gravito ja sen <span id='partners-link'>kolmannen osapuolen toimittajat</span> keräävät henkilötietoja (esim. IP-osoite tai laitetunniste) käyttäen evästeitä ja muita teknisiä keinoja tietojen tallentamiseen ja lukemiseen laitteellasi tarjotakseen sinulle tarkoituksenmukaisia mainoksia ja parhaan mahdollisen asiakaskokemuksen",
116
consentableItemDescription: "Gravito ja sen kumppanit tarvitsevat suostumuksesi seuraaviin:",
117
legalFooter: "Hyväksymällä sallit tietojesi käsittelyn. Suostumuksesi koskee tätä palvelua, hyväksymättä jättäminen voi vaikuttaa asiakaskokemukseesi. Jotkut teknologiat saattavat perustella tietojen käsittelyä oikeutetulla edulla, voit vastustaa tätä tai muuttaa muita asetuksia klikkaamalla \"Asetukset\" linkkiä.",
118
privacyPolicyUrl: "https://www.gravito.net/#privacy-policy",
119
privacyLabel:"Tietosuoja",
120
actions: ["Asetukset","Hyväksy kaikki"]
121
},
122
secondLayer: {
123
title: "Asetukset",
124
introductionText: "Valitse oheiselta listalta haluamasi tarkoitukset ja autat meitä palvelemaan sinua paremmin.",
125
tabLabels: ["Tarkoitukset ja ominaisuudet","Toimittajat"],
126
checkBoxLabels:{
127
"consent": "Suostumus",
128
"legitimateInterest": "Oikeutettu etu"
129
},
130
actions: ["Hyväksy kaikki","Hyväksy valitut","Estä kaikki"]
131
},
132
thirdLayer: {
133
confirmationForUncheck: {
134
heading: "Oletko varma että haluat olla antamatta suostumusta?",
135
paragraphs: [
136
"Nämä evästeet tai muut tekniset keinot ovat tärkeitä parhaan ja personoidun käyttäjäkokemuksen tuottamiseksi."
137
]
138
},
139
confirmationForAcceptSelected: {
140
heading: "Oletko varma että haluat olla antamatta suostumusta?",
141
paragraphs:[
142
"Nämä evästeet tai muut tekniset keinot ovat tärkeitä parhaan ja personoidun käyttäjäkokemuksen tuottamiseksi.",
143
"Ilman evästeitä tai muita vastaavia teknisiä keinoja on kykymme kehittää palveluitamme ja personoida käyttökokemustasi vaikeampaa, mistä johtuen voi olla että jotkin ominaisuudet ovat pois käytöstä ja käyttökokemuksesi voi olla heikompi."
144
]
145
},
146
actions: ["Peruuta","Kyllä"]
147
},
148
149
commonTerms:{
150
purposes:"Tarkoitukset",
151
consent:"Suostumus",
152
legitimateInterest:"Oikeutettu etu",
153
specialPurposes:"Erityiset tarkoitukset",
154
specialFeatures:"Erityisominaisuudet",
155
features:"Ominaisuudet",
156
policyURl:"Tietosuojaselosteen osoite",
157
nonTCFVendors:"Toimittajat jotka eivät kuulu IAB:n TCF verkostoon",
158
vendors:"Toimittajat",
159
customPurposes:"Graviton toimintaan liittyvät luvat"
160
}
161
},
162
style:{
163
logoUrl: "https://cdn.gravito.net/logos/gravito_logo_white_background.png",
164
primaryColor: "orange",
165
secondaryColor: "#666",
166
fonts: [
167
{
168
url:"https://fonts.gstatic.com/s/manrope/v1/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_M-bnBeA.woff2",
169
unicodeRange:"U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;"
170
},
171
{
172
url:"https://fonts.gstatic.com/s/manrope/v1/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_C-bk.woff2",
173
unicodeRange:"U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;"
174
}
175
],
176
customCSS:customCSS,
177
consentInputType:"toggle",
178
useAccordionForPurpose:true,
179
layoutType:"3-tabs",
180
disableConfirmationModal:true,
181
showCopyTcStringButton:true
182
}
183
}
184
window.gravitoCMPConfig = gravitoCMPConfig;
185
186
//TCF specific base url
187
var baseUrl="https://cdn.gravito.net/tcf-v2";
188
189
//js components specific base url
190
var componentUrl="https://cdn.gravito.net/cmp";
191
192
function browserSupportsSymbol(){
193
194
return window.Symbol?true:false;
195
}
196
var browserSupportsES6 = function() {
197
try {
198
new Function("(a = 0) => a");
199
return true;
200
}
201
catch (err) {
202
return false;
203
}
204
}();
205
function addPolyfill(){
206
207
var isSymbolPresent= browserSupportsSymbol();
208
var isEs6FeaturePresent= browserSupportsES6;
209
if(isSymbolPresent===false&&isEs6FeaturePresent===false){
210
var polyfillScriptTag = document.createElement('script');
211
polyfillScriptTag.src='https://polyfill.io/v3/polyfill.min.js?features=es6%2CSymbol';
212
polyfillScriptTag.addEventListener('load',function(){
213
addbundles()
214
})
215
document.head.appendChild(polyfillScriptTag);
216
return
217
}
218
if(isSymbolPresent===true&&isEs6FeaturePresent===false){
219
var polyfillScriptTag = document.createElement('script');
220
polyfillScriptTag.src='https://polyfill.io/v3/polyfill.min.js?features=es6';
221
polyfillScriptTag.addEventListener('load',function(){
222
addbundles()
223
})
224
document.head.appendChild(polyfillScriptTag);
225
return
226
}
227
if(isSymbolPresent===false&&isEs6FeaturePresent===true){
228
var polyfillScriptTag = document.createElement('script');
229
polyfillScriptTag.src='https://polyfill.io/v3/polyfill.min.js?features=Symbol';
230
polyfillScriptTag.addEventListener('load',function(){
231
addbundles()
232
})
233
document.head.appendChild(polyfillScriptTag);
234
return
235
}
236
237
addbundles()
238
239
240
}
241
//add stub
242
function addstub (){
243
var stubScriptTag = document.createElement('script');
244
stubScriptTag.innerHTML='"use strict";!function(){var e=function(){var e,t="__tcfapiLocator",a=[],n=window;for(;n;){try{if(n.frames[t]){e=n;break}}catch(e){}if(n===window.top)break;n=n.parent}e||(!function e(){var a=n.document,r=!!n.frames[t];if(!r)if(a.body){var s=a.createElement("iframe");s.style.cssText="display:none",s.name=t,a.body.appendChild(s)}else setTimeout(e,5);return!r}(),n.__tcfapi=function(){for(var e,t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return a;if("setGdprApplies"===n[0])n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0));else if("ping"===n[0]){var s={gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"};"function"==typeof n[2]&&n[2](s)}else a.push(n)},n.addEventListener("message",(function(e){var t="string"==typeof e.data,a={};try{a=t?JSON.parse(e.data):e.data}catch(e){}var n=a.__tcfapiCall;n&&window.__tcfapi(n.command,n.version,(function(a,r){var s={__tcfapiReturn:{returnValue:a,success:r,callId:n.callId}};t&&(s=JSON.stringify(s)),e&&e.source&&e.source.postMessage&&e.source.postMessage(s,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=e:e()}();'
245
246
document.head.appendChild(stubScriptTag)
247
}
248
249
function addPrivateConfig (){
250
window.gravitoCMP={
251
baseUrl:baseUrl
252
}
253
}
254
function addbundles (){
255
var ui_path= componentUrl + "/uibundle_latest.js"
256
var cmp_path=componentUrl + "/bundle_latest.js"
257
var el = document.createElement('script');
258
el.src = cmp_path
259
el.async = 'true';
260
el.addEventListener('load', function() {
261
var ui_script = document.createElement("script");
262
ui_script.src = ui_path;
263
document.head.appendChild(ui_script);
264
265
});
266
document.head.appendChild(el);
267
}
268
269
function initDataLayer(){
270
271
window.gravitoData?window.gravitoData.CMP = {}: createDataLayer();
272
}
273
274
function createDataLayer() {
275
window.gravitoData = {};
276
window.gravitoData.CMP = {};
277
}
278
279
addPrivateConfig();
280
addstub();
281
addPolyfill();
282
initDataLayer();
283
</script>
Copied!

Versioning

Above example links to always latest bundle libraries, doing so loads always the latest production build of Gravito CMP. If you want to stick on certain version and/or include your own QA control to the process, you can link the configuration to load specific versions by modifying these attributes within configuration:
1
var ui_path= componentUrl + "/uibundle-1.0.0.js"
2
var cmp_path=componentUrl + "/bundle-1.0.0.js"
Copied!

Inject CSS to CMP

custom CSS classes or other definitions can be injected to CMP, this helps with cases where base CSS on the site CMP runs on is too greedy and overrides styling over CMP.
Example of CSS injection, basically you need to define customCSS as first thing on the wrapper code:
1
var customCSS = ".gravitoCMP-list-heading { padding-top: 4px !important; font-size: 0.7em !important; margin-right: 0; }";
Copied!

Global scope

If you want to configure CMP to global scope, ie. consent string is set on euconsent-v2 cookie, you need to change configuration:
1
isServiceSpecific:false
Copied!
Google Ad Manager?
If you are using Google Ad Manager and you are seeing 2.1A errors on your reports, you might want to affect the ad tags and request personalized ads only when there is consent given via CMP. You can enable this e.g. by adding following script on your orchestration (requires CMP version 1.0.3 and googleTcfId to be configured):
1
<script>
2
if(gravitoCMP && gravitoCMP.eventsHandler.getGooglePersonalizationStatus()){
3
googletag.cmd.push(function(){
4
googletag.pubads().refresh();
5
});
6
}else{
7
googletag.cmd.push(function(){
8
googletag.pubads().setRequestNonPersonalizedAds(1);
9
googletag.pubads().refresh();
10
});
11
}
12
</script>
Copied!
Last modified 2mo ago