analytics
Count page views and button clicks, and send them to the analytics service you choose.
Every export of kitr/analytics, kitr/analytics/provider, kitr/analytics/react, read from the published type definitions. The guide shows them in use.
kitr/analytics
consoleAdapter
function consoleAdapter(options?: {
prefix?: string;
}): AnalyticsAdapter;
Logs every call. The default in development when no other adapter is configured.
createAnalytics
function createAnalytics<E extends EventMap = EventMap>(config?: AnalyticsConfig<E>): Analytics<E>;
One API over any number of destinations. Calls made before enable() queue (up to 100)
so a consent banner can gate everything, and every adapter call is wrapped so a blocked
script never breaks the app.
defineEvents
function defineEvents<E extends EventMap>(): <C extends AnalyticsConfig<E>>(config: C) => C & {
events?: E;
};
Identity helper that fixes the event map type: const analytics = createAnalytics<AppEvents>(...).
googleAnalytics
function googleAnalytics(options: {
measurementId: string;
debug?: boolean;
}): AnalyticsAdapter;
Google Analytics 4 through gtag.js. Loads the script on init() (client only) and
forwards page views, events and user ids. sendPageView: false is set on config so the
router, not the script, decides what a page view is.
memoryAdapter
function memoryAdapter(): AnalyticsAdapter & {
calls: Array<{
type: string;
args: unknown[];
}>;
};
Collects calls in memory. For tests: expect(adapter.calls).toContainEqual(...).
plausible
function plausible(options: {
domain: string;
apiHost?: string;
}): AnalyticsAdapter;
Plausible: one script, page() becomes a pageview, track() a custom event with props.
posthog
function posthog(client: PostHogLike, options: {
apiKey: string;
apiHost?: string;
config?: Record<string, unknown>;
}): AnalyticsAdapter;
PostHog through its own client (posthog-js), with autocapture of page views turned off so the router drives them.
defineConfig
const defineConfig: <const C extends AnalyticsConfig<EventMap>>(config: C) => C;
Analytics
interface Analytics<E extends EventMap = EventMap> {
page(path: string, props?: EventProps & {
url?: string;
title?: string;
}): void;
track<K extends keyof E & string>(event: K, ...props: E[K] extends undefined ? [
] : [
E[K]
]): void;
track(event: string, props?: EventProps): void;
identify(userId: string, traits?: EventProps): void;
reset(): void;
/** Flush the queue and start sending. Call after consent. */
enable(): Promise<void>;
/** Stop sending; calls are dropped (not queued) once disabled after being enabled. */
disable(): void;
readonly enabled: boolean;
/** Add an adapter at runtime (after a consent choice, or lazily). */
use(adapter: AnalyticsAdapter): void;
readonly adapters: readonly AnalyticsAdapter[];
}
AnalyticsAdapter
interface AnalyticsAdapter {
name: string;
/** Load scripts, create clients. Called once on the client when tracking is enabled. */
init?(): void | Promise<void>;
page(path: string, props?: EventProps & {
url?: string;
title?: string;
}): void;
track(event: string, props?: EventProps): void;
identify?(userId: string, traits?: EventProps): void;
reset?(): void;
}
What every destination implements. Methods are best-effort and must never throw into app code.
AnalyticsConfig
interface AnalyticsConfig<E extends EventMap = EventMap> {
adapters?: AnalyticsAdapter[];
/** Start sending immediately (default). Set false to queue until `analytics.enable()` (consent banners). */
enabled?: boolean;
/** Track route changes automatically through the router. Default true. */
pageViews?: boolean;
/** Props merged into every event (app version, build id). */
globalProps?: EventProps;
/** Log every call. Default: `app.environment` is development. */
debug?: boolean;
/** Phantom for `defineEvents`. */
readonly events?: E;
}
PostHogLike
interface PostHogLike {
init(token: string, config?: Record<string, unknown>): unknown;
capture(event: string, properties?: Record<string, unknown> | null): unknown;
identify(id?: string, properties?: Record<string, unknown>): void;
reset(): void;
}
Minimal shape of the posthog-js client; pass posthog from posthog-js or any compatible object.
EventMap
type EventMap = Record<string, EventProps | undefined>;
defineEvents<{ 'project.created': { id: string } }>() gives track() typed names and props.
EventProps
type EventProps = Record<string, unknown>;
kitr/analytics/provider
analyticsProvider
const analyticsProvider: import("@kitr/core").KitrProvider;
Binds analytics into the container from config/analytics.ts and, on the client,
tracks route changes. With no adapters configured, development logs to the console
and production sends nothing.
kitr/analytics/react
TrackPageViews
function TrackPageViews(): null;
Sends a page() on every resolved navigation. Mounted by the provider when
pageViews is not false; render it yourself if you build the tree by hand.
useAnalytics
function useAnalytics<E extends EventMap = EventMap>(): Analytics<E>;
The analytics instance from the container.