Lumeo
Package LumeoA11yfocus-managedkeyboarddialogregionDepends onflow-canvasTested Tier 3 · 69 testsView source ↗

Consent Banner

GDPR-ready cookie / tracking consent primitive. Persists per-category choices in localStorage and exposes them via ConsentService for gating third-party scripts.

Installation

dotnet add package Lumeo

One-time app setup (AddLumeo(), CSS & JS) is covered in the installation guide.

Usage

@using Lumeo

<ConsentBanner />
Tested Tier 3 · A11y + behavior
all components →
Render Behavior A11y Keyboard Scale E2E

69 tests across 16 files. Auto-generated from the test suite.

When to use

  • Any site that loads analytics (Google Analytics, Cloudflare Web Analytics, Plausible, Umami) in the EU / UK / CA.
  • Any site that embeds third-party scripts users should opt into (YouTube embeds, Intercom, Hotjar).
  • SaaS apps that want to give end users a "Manage cookie preferences" link in the footer.

Analytics consent right now: denied.

The banner in the docs site already ran once (accepted/declined at first visit). Click below to re-open its preferences dialog — it's the same API a consumer would wire to a footer link.

No live preview here — the banner can only show once per browser. Copy the code into your own MainLayout.razor to see it slide in.

Drop the banner into your root layout. Default categories are `necessary` (locked) + `analytics`.

Consent preferences
Pick which categories you're okay with. You can change this later.
Strictly necessaryRequired

Session, theme preference, routing — required for the site to work.

Analytics

Cloudflare Web Analytics — anonymous aggregate page-view stats.

Marketing

Meta Pixel and LinkedIn Insight Tag for remarketing.

Third-party embeds

YouTube, Vimeo, Tweet embeds — set cookies when loaded.

Define your own buckets — one per third-party service you load.

Cookies & consent

We use a minimal set of cookies to run the site and optionally measure anonymous usage to improve it. You choose what's on.

Every string is a parameter. Pair with `ILumeoLocalizer` if you want them to follow the user's language.

API reference

Prop Type Default Description
Class string? — Additional CSS classes merged onto the banner's root role="region" element (the preferences dialog is unaffected).
AdditionalAttributes Dictionary<string, object>? — Unmatched attributes splatted onto the banner's root role="region" element.
Categories IReadOnlyList<Lumeo.Services.ConsentCategory> DefaultCategories Consent buckets to expose in the preferences dialog. Omit `Required: true` ones if your site doesn't use strictly-necessary cookies.
PrivacyPolicyUrl string? — URL to your privacy policy page. If null, the link is hidden.
PolicyVersion string "1" Privacy-policy version this banner asks consent for. When a stored decision was recorded against a different version, the banner re-prompts (previous choices prefill the preferences dialog, but the user must re-confirm). Bump this whenever your policy materially changes. Defaults to "1".
Title string "Cookies & consent" Banner heading, shown next to the cookie icon.
Description string "We use a minimal set of cookies to run the site and optionally measure anonymous usage to improve it. You choose what's on." Banner body text, followed by the privacy-policy link when PrivacyPolicyUrl is set.
PrivacyPolicyLabel string "Read the privacy policy" Link text for the privacy-policy link (only shown when PrivacyPolicyUrl is set).
AcceptLabel string "Accept all" Label for the layer-1 "accept everything" button.
RejectLabel string "Reject optional" Label for the layer-1 "reject optional categories" button.
CustomizeLabel string "Customize" Label for the button that opens the preferences dialog; only rendered when at least one non-required category exists.
PreferencesTitle string "Consent preferences" Heading of the preferences dialog.
PreferencesDescription string "Pick which categories you're okay with. You can change this later." Body text of the preferences dialog.
RequiredBadge string "Required" Badge text shown next to a category that is Required: true (always on, not toggleable).
CancelLabel string "Cancel" Label for the preferences dialog's cancel button (discards draft changes).
SaveLabel string "Save preferences" Label for the preferences dialog's save button (commits the draft toggles).
AnimationClass string "animate-slide-in-from-bottom" CSS animation class applied to the banner on mount (default a slide-in from the bottom edge).
Property Type Description
KeystringMachine-readable identifier (e.g. "analytics"). Used as the persistence key and the argument to ConsentService.HasConsent(key).
TitlestringShort label shown in the preferences dialog.
DescriptionstringOne-sentence explanation for the end user.
RequiredboolLocked-on toggle. Use for strictly-necessary cookies (session, theme preference).
Member Description
bool HasDecidedTrue once the user has answered the banner. While false, the banner shows.
bool HasConsent(string key)Did the user consent to this category? "necessary" always returns true; unknown keys return false.
Task EnsureLoadedAsync()Hydrate from localStorage. Called automatically by the banner on first render; safe to call yourself before the banner mounts.
Task AcceptAllAsync(IEnumerable<string>)Grant every non-necessary category. Persists to localStorage. Fires OnChange.
Task RejectAllAsync(IEnumerable<string>)Deny every non-necessary category. Persists and fires OnChange.
Task SetManyAsync(IReadOnlyDictionary<string, bool>)Commit a per-category map. Used by the preferences dialog's Save button.
Task ResetAsync()Clear the stored decision — banner re-appears on next render.
void RequestOpenPreferences()Ask any mounted <ConsentBanner> to pop its dialog. Wire a "Cookie settings" footer link to this (as this site's footer does).
string PolicyVersionPolicy version to ask consent for. Set from the banner's PolicyVersion parameter; a stored decision from another version re-prompts.
DateTimeOffset? DecidedAtUtcUTC timestamp of the last recorded decision (proof of consent), or null if none stored.
string? DecisionPolicyVersionPolicy version the last recorded decision was given against. Null for a legacy (versionless) record.
event Action? OnChangeFires when any category value changes. Subscribe if you want to dynamically load / unload scripts.
event Action? OnRequestOpenPreferencesInternal coordination between RequestOpenPreferences and the banner.