Under GDPR and the ePrivacy rules, a site has to tell visitors which cookies it sets and why. It also has to let them refuse the ones that are not strictly necessary. Cendia supplies the mechanism. The site supplies the question: where the choice appears (a banner, a privacy page, a footer link) and how it reads is a design decision, just like a language switcher.
This page is the list to build that notice from.
Cookies Cendia sets for visitors
| Cookie | Set when | Lifetime | Purpose | Necessary? |
|---|---|---|---|---|
cms_Visitor |
Visitor tracking is on | 1 year, renewed on each visit | A random id for this browser. Page views are recorded against it for the visit-history audience criteria. | No: personalisation |
cms_Session |
Visitor tracking is on | 30 minutes, renewed on each request | A random id for this visit. A visit ends after 30 minutes with no page view. Used by Time on Site, Number of Visits and the Forms criterion's "Session" option. | No: personalisation |
cms_TrackingOptOut |
The visitor opts out | 1 year | Remembers the opt-out. | Yes: it is the refusal |
mcform-sent-{form id} |
A form that allows only one submission is sent | 1 year | Stops the same browser sending that form twice. | Yes: requested by the visitor's own action |
.AspNetCore.Antiforgery.* |
A page renders a form | Browser session | Protects form posts from cross-site forgery. | Yes: security |
.AspNetCore.Mvc.CookieTempDataProvider |
A form post redirects back | Until read | Carries a form's errors or thank-you message across the redirect. | Yes |
Visitor tracking is off by default. With Cendia:EnableVisitorTracking unset, neither
cms_Visitor nor cms_Session is ever written.
Cookies for people signed in to the CMS
These reach only authors and administrators, never an anonymous visitor.
| Cookie | Purpose |
|---|---|
.AspNetCore.Identity.Application |
The CMS login. |
.AspNetCore.Antiforgery.* |
Form protection in the editor. |
Cookies your site sets
The starter code uses cookies of its own. They belong to your site, so list them if you keep them:
| Cookie | Purpose | Necessary? |
|---|---|---|
site.theme |
The visitor's light or dark choice. | Yes: a preference they set |
site.lang |
The visitor's language choice (Arena's switcher). | Yes: a preference they set |
What visitor tracking records
With tracking on, each rendered page view writes one row to cms_Collection_VisitorActivity:
- the
cms_Visitorandcms_Sessionids - the path viewed, and its first segment
- the language it was served in
- the time
- the IP address, which is personal data under GDPR. It is stored so that Number of Visits can count visits per address.
The JSON Delivery API, previews and the CMS editor are never recorded.
The Geographic Location criterion looks a visitor's address up in a database on your own server when a page is requested. It sets no cookie, stores nothing, and sends the address nowhere. See Geographic location.
Rows are deleted once they are older than Cendia:VisitorActivityRetentionDays, 90 by default.
The Visitor Activity Retention scheduled job runs that sweep every hour.
{
"Cendia": {
"EnableVisitorTracking": true,
"VisitorActivityRetentionDays": 90
}
}
Letting visitors opt out
Cendia.AspNetCore.Audiences.VisitorTrackingConsent holds the building blocks:
using Cendia.AspNetCore.Audiences;
http.OptOutOfVisitorTracking(); // sets cms_TrackingOptOut, removes cms_Visitor and cms_Session
http.OptInToVisitorTracking(); // removes the opt-out; tracking resumes under new ids
http.IsVisitorTrackingOptedOut(); // for showing the current choice
After opting out:
- No tracking cookie is set.
- No page view is recorded.
- Form submissions carry no visit id.
Every audience criterion that depends on tracking simply does not match for that visitor: Number of Visits, Time on Site, Visited Page (history), Visited Category, and Forms by session. Nothing errors, and the page renders exactly as it would for anyone outside the audience.
The development server (Cendia.Server) shows one way to offer the choice. Its footer carries a
Personalisation: on / off link, mapped in TrackingPreference.cs:
app.MapGet("/set-tracking", (HttpContext http, string choice, string? returnUrl) =>
{
if (choice == "off") http.OptOutOfVisitorTracking();
else if (choice == "on") http.OptInToVisitorTracking();
return Results.Redirect(SafeReturnUrl.Or(returnUrl));
});
A consent banner that asks before tracking starts works the same way. Opt the visitor out until they agree, then opt them in.
Signed-in visitors
The Forms criterion's "Logged in" option, and a form set to accept only signed-in visitors, need
a sign-in for the site's visitors. The CMS login does not count. Cendia ships none. Your
site registers one by implementing IVisitorIdentity:
public sealed class MyVisitorIdentity : IVisitorIdentity
{
public AudienceVisitor? Current(HttpContext http) =>
/* read your own sign-in: its user id, email and roles */;
}
builder.Services.AddScoped<IVisitorIdentity, MyVisitorIdentity>();
The development server's SiteIdentity.cs is a complete example built on ASP.NET Identity. It has
its own user table and its own site.auth cookie, kept apart from the CMS login.