Consent and cookie banner
The app can record what the user does in the store, such as the products they view or what they add to the cart, to send them reminders like the abandoned cart one. It can also measure app usage with Firebase Analytics. Both need the user’s consent.
That consent is usually requested in the website’s cookie banner. Inside the app,
the banner has to tell the app what the user has chosen. A single JavaScript
call, window.ReskytLayout.consent.set(...), in the buttons the banner already
has, is enough.
What your web team has to do
Section titled “What your web team has to do”- Add a function to the website’s JavaScript that translates the banner’s choice into the app’s format.
- Call it every time the user accepts, rejects or saves their preferences, and also on every page load if they had already answered.
- Keep a permanent link to the cookie settings inside the app, so the user can change their mind.
window.ReskytLayout only exists inside the app. In a normal browser the call
does nothing, so the same code works for the website and for the app.
What the user decides
Section titled “What the user decides”Each banner group corresponds to one or more app keys:
| Banner group | What it allows in the app | Key | If the user has not answered yet |
|---|---|---|---|
| Strictly necessary | Nothing additional. | None | Always on. |
| Analytics | Firebase Analytics measuring app usage. | analyticsStorage | On, unless the Firebase Analytics module settings say otherwise. |
| Personalisation or behavioural | The User Journal recording shopping activity, and reminders based on it, such as the abandoned cart one. | journal | Off in every app. |
| Advertising | Advertising cookies and identifiers, sending data to Google for advertising, and personalised advertising. | adStorage, adUserData and adPersonalization | Off. |
The analytics and advertising keys correspond to Google’s consent mode keys
(analytics_storage, ad_storage, ad_user_data and ad_personalization) and
are passed to Firebase one to one. If analyticsStorage is off, Firebase
collects nothing.
How the app remembers it
Section titled “How the app remembers it”The app stores the answer on the device itself, together with the date. From then on:
- It does not ask again. The answer is kept even if the app is closed, and Reskyt does not request it again.
- It applies at once. The app checks the answer every time it is about to record something, so a change mid-session takes effect immediately, in both directions.
- The last answer wins. It does not matter whether it comes from the website’s banner or from Reskyt’s consent page.
Step 1: add the function
Section titled “Step 1: add the function”This function receives the groups the user has accepted in the banner and passes them to the app. It can go anywhere in the website’s JavaScript:
function applyAppConsent(groups) { const consent = window.ReskytLayout?.consent; // Outside the app, or if the app is not ready yet, it does nothing if (!consent?.isAvailable()) return;
consent.set({ journal: groups.behavioural === true, analyticsStorage: groups.analytics === true, adStorage: groups.advertising === true, adUserData: groups.advertising === true, adPersonalization: groups.advertising === true, });}The names behavioural, analytics and advertising are an example: replace
them with the ones your banner uses. A group that does not arrive as true is
turned off.
Step 2: call it from the banner
Section titled “Step 2: call it from the banner”The function is called at four moments, always the same way:
| When | What is called |
|---|---|
| The user clicks Accept all | applyAppConsent({ analytics: true, behavioural: true, advertising: true }) |
| The user clicks Reject all or Only necessary | applyAppConsent({}), which turns everything off |
| The user saves their preferences | applyAppConsent(...) with the value of each checkbox |
| A page loads and the user had already answered | applyAppConsent(...) with the answer the website has stored |
The last case keeps the app aligned with the answer the website stores, for example in a cookie, even if the banner is not shown again.
If the website uses a consent manager, the call is made from the event the manager fires when the choice changes, instead of from the buttons:
| Manager | Event |
|---|---|
| OneTrust | OptanonWrapper() |
| Cookiebot | CookiebotOnAccept and CookiebotOnDecline |
| Didomi | consent.changed |
The accepted groups are read from the manager’s own API.
Step 3: let the user change their mind
Section titled “Step 3: let the user change their mind”Withdrawing consent must be as easy as giving it. Keep a permanent link to the
cookie settings inside the app, in the footer or the menu, that reopens the
banner. If the user rejects from there, the banner calls applyAppConsent({}) or
directly ReskytLayout.consent.set('none').
To make the app ask again, for example when the consent stored on the website
expires, call ReskytLayout.consent.reset().
Alternative: Reskyt’s consent page
Section titled “Alternative: Reskyt’s consent page”Instead of your own banner, the website can open the consent page included in the app:
window.ReskytLayout.screens.openSystemPage('consent');The app never opens it on its own: it has to be called from the website’s code, for example from a button. The page only needs to be published in the backoffice; it needs no other setting.
If the device asks not to be tracked
Section titled “If the device asks not to be tracked”If the device’s browser has a privacy option such as Do Not Track or Global Privacy Control turned on, the app turns everything off, whatever the banner answered.
Check that it works
Section titled “Check that it works”Open the app on a test device with the web inspector attached, from
chrome://inspect on Android or from Safari’s Develop menu on iOS, and run
ReskytLayout.consent.get() in the console:
| Situation | What it should return |
|---|---|
| Before answering the banner | status: 'undecided' and journal: false |
| After Accept all | status: 'decided', source: 'user' and every key true |
| After Reject all from the cookie settings | Every key false |
If it returns source: 'browser' with everything off, the device has a browser
privacy option turned on, as explained in the previous section.
API reference
Section titled “API reference”Methods
Section titled “Methods”| Method | What it does |
|---|---|
isAvailable() | Indicates whether the API can be used. Returns false outside the app. |
get() | Returns the stored answer. |
set(choice) | Stores an answer. Returns a promise with the new state. |
reset() | Clears the answer and returns to the unanswered state. |
onChange(listener) | Runs listener every time the answer changes. Returns a function to stop listening. |
set accepts three forms:
| Value | Effect |
|---|---|
'all' | Turns everything on. |
'none' | Turns everything off. |
An object, for example { journal: true } | Changes only the given keys. The rest keep their value. |
You can store your own keys, with letters, digits and underscore up to 64
characters. The app stores them and returns them in get(), but does not use
them.
get() returns an object with this shape:
{ status: 'decided', source: 'user', decidedAt: '2026-10-21T09:12:00.000Z', categories: { journal: true, analyticsStorage: true, adStorage: false, adUserData: false, adPersonalization: false }}| Field | Meaning |
|---|---|
status | 'undecided' if the user has not answered yet, 'decided' if they have. |
source | Where the value comes from: 'default', the default values; 'user', the user’s answer; 'browser', a browser privacy option that turns everything off. |
decidedAt | Date of the answer. |
categories | The value of each key. |
To read it from the website, for example to not show the banner inside the app if the user has already answered:
const consent = window.ReskytLayout?.consent;if (consent?.get().status === 'decided') hideBanner();consent?.onChange((state) => console.log(state.categories));