ComponentsSite blocks

Cookie / consent banner

Cookie consent for GDPR / ePrivacy and Turkey's KVKK, wired to Google Consent Mode v2. Not a modal: a labelled region that never blocks the page or steals focus, with “Reject all” and “Accept all” at equal size and weight on the first layer. Preferences open in a Dialog with one Switch per category, none pre-checked. Choices live in a first-party vb_consent cookie (6 months, versioned); getConsent / onConsent let other code wait for a category, and ConsentGate keeps maps and videos behind a facade. Without JS nothing renders and no non-essential cookie is set. Default texts are neutral templates — review them with counsel.

Dialog + Switch blocks/site/consent-banner.tsx, blocks/site/shared/consent-island.tsx, blocks/site/shared/consent.ts, blocks/site/shared/consent-gate.tsx, blocks/site/registry-2.ts, styles/blocks.csstheme · material · accent · density · font

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { ConsentBanner, consentDefaultsScript, onConsent } from "@vamos-ui/react/blocks";

// app/layout.tsx
<head><script dangerouslySetInnerHTML={{ __html: consentDefaultsScript({ version: 2 }) }} /></head>
<body>
  {children}
  <ConsentBanner version={2} policyLink={{ href: "/cookies" }} />
</body>

// anywhere on the client
onConsent("analytics", () => loadAnalytics());

Examples

Box (Turkish)

A 360px panel for the bottom-start corner, buttons stacked; zorunlu / işlevsel / analitik / pazarlama.

Preferences

Open “Preferences”: Switches with descriptions, Necessary locked on, Reject / Accept / Save.

ConsentGate for maps and video

A static preview with one button; the iframe loads on click, or automatically once the category is granted. “Always load maps” grants functional for the site.

The map loads from Google Maps, which may set cookies.

Hosted by YouTube, which may set cookies.

API

ConsentBanner

PropTypeDefault
variant
Bottom strip, or a corner panel.
"bar" | "box""bar"
text
The notice; rich text may contain links.
ReactNode | RichDocneutral template
policyLink
Cookie policy link.
{ href; label? }—
categories
Necessary is always on.
("necessary" | "functional" | "analytics" | "marketing")[]all four
version
Bump when text or categories change: visitors are asked again.
number1
position
Default bottom (bar) / bottom-start (box).
"bottom" | "bottom-start"—
regionMode
opt-in for GDPR/KVKK; notice only where the law allows.
"opt-in" | "notice""opt-in"
contained / forceShow / defaultPreferencesOpen
Previews and builder canvases.
boolean—
labels / locale
All banner and dialog strings (site2LabelsTr).
Partial<Site2Labels> / string—

Consent helpers

PropTypeDefault
getConsent(category, version?)
Is the category granted now?
boolean—
onConsent(category, fn)
Runs fn once the category is granted (now or later). Returns unsubscribe.
() => void—
writeConsent / readConsent / parseConsent(cookieHeader)
The vb_consent record; parseConsent also works on the server.
functions—
openConsentPreferences()
Reopens the dialog (Footer's “Cookie settings” uses ConsentSettingsButton).
void—
consentDefaultsScript(opts) / <ConsentDefaults />
Consent Mode v2 defaults for <head>.
string / element—

ConsentGate

PropTypeDefault
src / title
Iframe URL and its accessible title.
string—
category
Granted category that loads it automatically.
ConsentCategory"functional"
loadLabel / notice / rememberLabel
Button, provider notice, optional “always load” checkbox.
string / ReactNode / string—
aspect / allow / defaultLoaded
Frame ratio, iframe allow list, load at once.
string / string / boolean—
children
Static preview (decorative).
ReactNode—