API reference

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.

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.