consent
Every export of @kitr/consent, @kitr/consent/react, @kitr/consent/provider, read from the published type definitions. The guide shows them in use.
@kitr/consent
createConsent
function createConsent(config?: ConsentConfig, app?: KitrApp): Consent;
Build a consent service backed by a cookie. The provider calls it with the app (for devtools logging); tests and server code can call it without one.
useConsent
function useConsent(app: KitrApp): Consent;
The consent service from an app's container. Not a hook; components use useConsent() from @kitr/consent/react.
defineConfig
const defineConfig: <const C extends ConsentConfig>(config: C) => C;
Types the default export of config/consent.ts.
Consent
interface Consent {
/** The record, with `decidedAt` unset while the banner should show. */
get(): ConsentRecord;
/** Has the visitor decided (for this version)? */
decided(): boolean;
/** Whether a category is granted for the current version. Always true for `necessary`. */
has(category: ConsentCategory): boolean;
/** Grant exactly these categories (plus `necessary`). */
grant(categories: ConsentCategory[]): void;
/** Grant every configured category. */
acceptAll(): void;
/** Decline everything but `necessary`. */
rejectAll(): void;
/** Forget the choice so the banner shows again. */
reset(): void;
/** Call `listener` after every change to the choice. Returns the unsubscribe function. */
subscribe(listener: (record: ConsentRecord) => void): () => void;
/** The categories from config, in order. */
readonly categories: ConsentCategory[];
/** The storage cookie that holds the record; `cookie.get(request.headers)` reads it on the server. */
readonly cookie: CookieItem<ConsentRecord>;
}
The consent service bound as consent in the container. Reads and writes the visitor's choice.
ConsentConfig
interface ConsentConfig {
/** What the banner offers. Default `['analytics', 'marketing']`. */
categories?: ConsentCategory[];
/** Re-ask when this changes. Default 1. */
version?: number;
/** Cookie name. Default `consent`. */
cookie?: string;
/** Days the choice is kept. Default 365. */
maxAge?: number;
/** Which category analytics waits for. Default `analytics`; false never gates it. */
analytics?: ConsentCategory | false;
/** Which category error monitoring waits for. Default: none (monitoring runs; set `'analytics'` to gate it). */
monitoring?: ConsentCategory | false;
}
Options for config/consent.ts: the categories offered, the version, the cookie and what to gate.
ConsentRecord
interface ConsentRecord {
/** Categories the visitor agreed to. `necessary` is always in. */
granted: ConsentCategory[];
/** ISO time of the choice; undefined until they chose. */
decidedAt?: string;
/** Bump `config.version` to ask everyone again. */
version: number;
}
What a visitor agreed to, stored as JSON in the consent cookie.
ConsentCategory
type ConsentCategory = 'necessary' | 'analytics' | 'marketing' | 'preferences' | (string & {});
A consent category. necessary is always granted; the others are whatever config.categories lists.
@kitr/consent/react
useConsent
function useConsent(): {
record: ConsentRecord;
decided: boolean;
has: (category: ConsentCategory) => boolean;
categories: ConsentCategory[];
grant: Consent['grant'];
acceptAll: () => void;
rejectAll: () => void;
reset: () => void;
};
The consent record and the actions a banner needs; re-renders when the choice changes. The server cannot read the choice, so the server render and the hydrating render both see "undecided", and the stored choice arrives right after: no hydration mismatch.
@kitr/consent/provider
consentProvider
const consentProvider: import("@kitr/core").KitrProvider;
Binds consent and gates the trackers: analytics stays queued until its category is granted
(and is disabled again when it is withdrawn); monitoring is gated only when config.monitoring
names a category. Put the provider after the analytics and monitoring ones in kitrrc.ts.