Consent
Consent comes down to three parts: the text the visitor agrees to, their decision, and what happens because of it. EventRail takes care of the decision and the session identifier. The rest is yours.
| Part | EventRail | You |
|---|---|---|
| The consent text | Nothing | Write what the visitor agrees to, and what you won't do with their data. |
| The decision | Stores it in a cookie and adds it to every event. | Show a banner and pass the answer to setConsent(). |
| Acting on the decision | Stores the sessionId or not, as the storage policy says. | Decide whether and how each event is stored. |
The consent text
Your banner tells the visitor what they agree to: what you do with their data, and what you don't. EventRail doesn't show or check this text. Whatever it promises, the rest of your setup has to keep. See Acting on the decision.
The decision
The decision is one of three values:
| Value | Meaning |
|---|---|
"unset" | The visitor hasn't answered yet. |
"accepted" | The visitor agreed. |
"denied" | The visitor refused. |
"unset" and "denied" are different: a visitor who hasn't been asked yet is not one who said no.
When the visitor answers, call producer.setConsent("accepted") or producer.setConsent("denied").
This stores the decision in the EventRailConsent cookie, for 180 days by default (set with
consentMaxAge), and creates or removes the session identifier right away, as the storage policy
allows. setConsent("unset") clears the decision. In React, producer.useConsent() returns the
current decision, for example to show or hide your banner.
Every event carries the decision in effect when the Hub received it, in its consent field. See
the EventRecord examples.
Events sent before the visitor answers carry consent: "unset", which can split one visit in two.
Under optIn, the pages before the answer have no sessionId, so nothing links them to the
session that follows. Under optOut, a visitor who refuses leaves a session made up of the pages
they saw before answering. To keep events consistent, we suggest a banner that has to be answered
before the page can be used, with the browser producer holding events until it is. See
Blocking consent banner.
Acting on the decision
EventRail acts on the decision in one place: the session identifier. Everything else, including whether an event is stored at all, is up to you.
Storage policies
The storeSessionId option on the browser producer sets the policy. For each decision, it says
whether the session identifier cookie is stored:
| Policy | unset | accepted | denied |
|---|---|---|---|
enabled | store | store | store |
disabled | no store | no store | no store |
optIn | no store | store | no store |
optOut | store | store | no store |
Events are collected under every policy. When no identifier is stored, their sessionId is null.
Storing events
Every event reaches your destinations, whatever the decision.
Its consent field lets the systems downstream decide what to do with it.
If the law or your consent text requires you not to store events without consent, wrap a
destination so it only writes records whose consent is "accepted":
Next.js · lib/accepted-only.ts
import type { Destination } from "@eventrail/nextjs/core";
export function acceptedOnly(destination: Destination): Destination {
return {
name: destination.name,
async write(record) {
if (record.consent === "accepted") await destination.write(record);
},
};
}Then pass your destination through it:
Next.js · lib/eventrail-hub.ts
import "server-only";
import { createHub } from "@eventrail/nextjs/server";
import { createFileDestination } from "@eventrail/nextjs/destinations/file";
import { acceptedOnly } from "./accepted-only";
export const hub = createHub({
destinations: [acceptedOnly(createFileDestination({ path: ".data/events.ndjson" }))],
});A record with consent: "unset" or "denied" then never reaches the file. Other destinations in
the list still receive it. See Your own destination
for what a destination must do.