Skip to content

Commit 6a384ad

Browse files
committed
Added "Integration with Mobile Application" documentation
- added markdown file `docs/integration-with-mobile-application.md` - added images - added new section "Integration with Mobile Application" in the README
1 parent 3f5957d commit 6a384ad

10 files changed

+229
-4
lines changed

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ An extended integration of [orestbida/cookieconsent](https://github.com/orestbid
2323
* [Triggering tags based on the consent](#triggering-tags-based-on-the-consent)
2424
* [Accessing the wrapper in the JavaScript](#accessing-the-wrapper-in-the-javascript)
2525
* [Integration with CMP application](#integration-with-cmp-application)
26+
* [Integration with Mobile Application](#integration-with-mobile-application)
2627
* [How the GTM integration works](#how-the-gtm-integration-works)
2728
* [How to update already published container](#how-to-update-already-published-containers)
2829
* [Migration from v0.4 to v0.5](#migration-from-v04-to-v05)
@@ -192,10 +193,10 @@ You can define a message that will be displayed in the consent modal's descripti
192193

193194
### Page scripts
194195

195-
| Field | Description |
196-
|---------------------|----------------------------------------------------------------------|
197-
| Manage page scripts | Enable if you want to easily manage existing `<script>` tags. |
198-
| Script selector | The name of a data attribute that is used for managed <script> tags. |
196+
| Field | Description |
197+
|---------------------|------------------------------------------------------------------------|
198+
| Manage page scripts | Enable if you want to easily manage existing `<script>` tags. |
199+
| Script selector | The name of a data attribute that is used for managed `<script>` tags. |
199200

200201
Managing page scripts is disabled by default. When the feature is enabled then the following notation can be used for scripts you want to manage:
201202

@@ -399,6 +400,12 @@ Below this field you can define which columns the cookie table should contain.
399400

400401
<img src="docs/images/widget-with-cookie-tables.png" alt="Widget with cookie tables" width="600">
401402

403+
## Integration with Mobile Application
404+
405+
Integration with the mobile application is described in a separate document:
406+
407+
[Integration with Mobile Application](docs/integration-with-mobile-application.md).
408+
402409
## How the GTM integration works
403410

404411
#### Consent initialization
362 KB
Loading
22.7 KB
Loading
293 KB
Loading
277 KB
Loading
170 KB
Loading
172 KB
Loading
119 KB
Loading
98.5 KB
Loading
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<div align="center" style="text-align: center; margin-bottom: 50px">
2+
<img src="images/logo.svg" alt="Cookie Consent Logo" align="center" width="250">
3+
<h1 align="center">Integration with Mobile Application</h1>
4+
</div>
5+
6+
This document describes the concept of integrating with a mobile application using a [WebView](https://github.com/react-native-webview/react-native-webview) component in **React Native**.
7+
8+
* [Prerequisites](#prerequisites)
9+
* [Mobile Application Detection](#mobile-application-detection)
10+
* [GTM Trigger Setup](#gtm-trigger-setup)
11+
* [GTM Tag Setup](#gtm-tag-setup)
12+
* [How It Works](#how-it-works)
13+
* [Integration with Consent Management Platform](#integration-with-consent-management-platform)
14+
15+
## Prerequisites
16+
17+
- **Cookie Consent** integrated via GTM
18+
- A dedicated URL available on the website (e.g. `/mobile-app-cookies`) that renders no content. This page is used to display the cookie banner within the mobile application.
19+
20+
## Mobile Application Detection
21+
22+
Detection of the mobile app is necessary in order to determine whether the website is being rendered in a regular browser or within a WebView.
23+
This can be achieved by setting a custom `User-Agent` header from the mobile app, for example: `MyApp/1.0.0`.
24+
25+
In GTM, create a variable named `navigator.userAgent` of type **JavaScript Variable** with the value `navigator.userAgent`.
26+
27+
<img src="images/integration-with-mobile-application/gtm-variable-user-agent.png" alt="GTM Variable navigator.userAgent" width="600">
28+
29+
## GTM Trigger Setup
30+
31+
Two triggers must be defined for proper functionality.
32+
33+
The first trigger named `cookieConsent.mobileApp.webview` should be of type **Page View - DOM Ready** with the following conditions:
34+
35+
1. `{{navigator.userAgent}}` contains `MyApp`
36+
2. `{{Page Path}}` does not equal `/mobile-app-cookies`
37+
38+
This trigger runs only within the mobile app context and on all URLs except `/mobile-app-cookies`.
39+
40+
<img src="images/integration-with-mobile-application/gtm-trigger-cookieConsent-mobileApp-webview.png" alt="GTM Trigger cookieConsent.mobileApp.webview" width="600">
41+
42+
The second trigger named `cookieConsent.mobileApp.settings` should also be of type **Page View - DOM Ready** with the following conditions:
43+
44+
1. `{{navigator.userAgent}}` contains `MyApp`
45+
2. `{{Page Path}}` equals `/mobile-app-cookies`
46+
47+
This trigger runs only within the mobile app context and exclusively on the `/mobile-app-cookies` URL.
48+
49+
<img src="images/integration-with-mobile-application/gtm-trigger-cookieConsent-mobileApp-settings.png" alt="GTM Trigger cookieConsent.mobileApp.settings" width="600">
50+
51+
## GTM Tag Setup
52+
53+
Corresponding to the triggers, two GTM tags are required.
54+
55+
The first tag of type "Custom HTML", named `Cookie Consent - Mobile App WebView`, is triggered by `cookieConsent.mobileApp.webview`.
56+
57+
This tag performs the following actions:
58+
59+
- Hides the cookie banner entirely using a `<style>` block so it does not appear within the WebView.
60+
- If no valid consent is detected, a `postMessage` is sent to notify the app.
61+
62+
<details>
63+
<summary>Click to view the code</summary>
64+
65+
```html
66+
<script>
67+
window.cookieConsentWrapperEvents = window.cookieConsentWrapperEvents || [];
68+
69+
window.cookieConsentWrapperEvents.push(['init', function () {
70+
var plugin = window.CookieConsentWrapper.unwrap();
71+
72+
if (!plugin.validConsent() && 'ReactNativeWebView' in window) {
73+
window.ReactNativeWebView.postMessage(JSON.stringify({
74+
consent: null,
75+
source: null,
76+
}));
77+
}
78+
}]);
79+
</script>
80+
81+
<style>
82+
#cc--main {
83+
display: none !important;
84+
}
85+
</style>
86+
```
87+
</details>
88+
89+
<img src="images/integration-with-mobile-application/gtm-tag-webview.png" alt="GTM Tag Cookie Consent - Mobile App WebView" width="600">
90+
91+
The second tag of type "Custom HTML", named `Cookie Consent - Mobile App Settings`, is triggered by `cookieConsent.mobileApp.settings`.
92+
93+
This tag performs the following actions:
94+
95+
1. Hides the consent modal and close button of the settings modal using a `<style>` block.
96+
2. Immediately opens the settings modal and prevents it from being closed.
97+
3. Once the user interacts (clicks a button), consent is sent to the app using `postMessage`.
98+
99+
<details>
100+
<summary>Click to view the code</summary>
101+
102+
```html
103+
<script>
104+
window.cookieConsentWrapperEvents = window.cookieConsentWrapperEvents || [];
105+
106+
window.cookieConsentWrapperEvents.push(['init', function () {
107+
var plugin = CookieConsentWrapper.unwrap();
108+
109+
plugin.hideSettings = function () {};
110+
111+
plugin.showSettings(0);
112+
113+
document.querySelectorAll('#s-bns .c-bn, #c-bns .c-bn').forEach(function (button) {
114+
button.addEventListener('click', function () {
115+
setTimeout(function () {
116+
var consent = CookieConsentWrapper.consentCookieData;
117+
118+
if (null === consent) {
119+
return;
120+
}
121+
122+
var queryParameters = new URLSearchParams(window.location.search);
123+
var message = {
124+
consent: consent,
125+
source: queryParameters.get('source') || 'default',
126+
};
127+
128+
if ('ReactNativeWebView' in window) {
129+
window.ReactNativeWebView.postMessage(JSON.stringify(message));
130+
}
131+
}, 0);
132+
});
133+
});
134+
}]);
135+
</script>
136+
137+
<style>
138+
#cc_div #cm, #s-c-bn {
139+
display: none !important;
140+
}
141+
142+
/* Possibly other styles to customize the look ... */
143+
</style>
144+
```
145+
</details>
146+
147+
<img src="images/integration-with-mobile-application/gtm-tag-settings.png" alt="GTM Tag Cookie Consent - Mobile App Settings" width="600">
148+
149+
## How It Works
150+
151+
The mobile application must listen for incoming messages sent via `postMessage` from the GTM tags inside the WebView.
152+
Each message follows this format:
153+
154+
```json5
155+
{
156+
"source": "default", // string or null
157+
"consent": {} // object representing the full user consent, equivalent to what is stored in cookies
158+
}
159+
```
160+
161+
When a message is received with a `null` value in the `consent` field, the app should open the WebView with the URL `/mobile-app-cookies` and prompt the user for consent.
162+
163+
When a message with a populated `consent` object is received, the app should hide the WebView and persist the consent.
164+
165+
The mobile app must also ensure that a cookie (default name `cc-settings`) containing the user's consent is always available (if the consent has been stored) in the WebView context, so the banner reflects the current consent state.
166+
167+
```mermaid
168+
sequenceDiagram
169+
participant App as Mobile App
170+
participant WebView as WebView (/)
171+
participant GTM_WV as GTM Tag: Cookie Consent - Mobile App WebView
172+
participant SettingsView as WebView (/mobile-app-cookies)
173+
participant GTM_Set as GTM Tag: Cookie Consent - Mobile App Settings
174+
175+
App->>WebView: Load WebView with default URL (not /mobile-app-cookies)
176+
WebView->>GTM_WV: DOM Ready → Trigger WebView tag
177+
alt No valid consent
178+
GTM_WV-->>App: postMessage({ consent: null, source: null })
179+
App->>SettingsView: Load WebView with /mobile-app-cookies
180+
SettingsView->>GTM_Set: DOM Ready → Trigger Settings tag
181+
GTM_Set->>SettingsView: Show settings modal, wait for user action
182+
SettingsView-->>App: postMessage({ consent: {...}, source: "default" })
183+
App->>SettingsView: Hide WebView
184+
App->>App: Store consent
185+
else Valid consent
186+
GTM_WV-->>App: No action needed (consent valid)
187+
end
188+
189+
App->>WebView: Ensure "cc-settings" cookie is available (if stored)
190+
```
191+
192+
## Integration with Consent Management Platform
193+
194+
When integrating with the [Consent Management Platform (CMP)](https://github.com/68publishers/consent-management-platform), it is recommended to distinguish cookie definitions using separate environments.
195+
This is especially useful because the set of cookies used in a mobile application may differ from those on the website.
196+
Doing so ensures that the appropriate cookies are shown in the cookie table within the settings modal for each environment.
197+
198+
<img src="images/integration-with-mobile-application/cmp-settings-environments.png" alt="CMP Settings - Environments" width="600">
199+
200+
It is also advisable to distinguish environments when storing user consents, so the CMP dashboard clearly shows whether consent originated from the website or the mobile application.
201+
202+
To achieve this, a GTM variable named `cmp.environment` of type **Custom JavaScript** can be created:
203+
204+
<details>
205+
<summary>Click to view the code</summary>
206+
207+
```javascript
208+
function () {
209+
return {{navigator.userAgent}}.includes('MyApp') ? 'mobile' : 'default';
210+
}
211+
```
212+
</details>
213+
214+
<img src="images/integration-with-mobile-application/gtm-variable-cmp-environment.png" alt="GTM Variable - cmp.environment" width="600">
215+
216+
This variable should then be used in the field **Integration > CMP API > Environment code**:
217+
218+
<img src="images/integration-with-mobile-application/gtm-cmp-environment-settings.png" alt="GTM Tag - CMP Environment settings" width="300">

0 commit comments

Comments
 (0)