analytics
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;
Types the default export of config/analytics.ts: adapters, consent queueing, page views and global props.
Analytics
interface Analytics<E extends EventMap = EventMap> {
/** Record a page view. The provider calls it on every route change unless `pageViews` is false. */
page(path: string, props?: EventProps & {
url?: string;
title?: string;
}): void;
/**
* Record an event. With an event map (`useAnalytics<AppEvents>()`), only its names are accepted,
* each with its own props; without one, any name and props.
*/
track: Track<E>;
/** Attach later events to a user id, after sign-in. `globalProps` are not added. */
identify(userId: string, traits?: EventProps): void;
/** Forget the identified user, on sign-out. */
reset(): void;
/** Load each adapter's script, then send the queued calls and start sending. Call after consent. */
enable(): Promise<void>;
/** Stop sending and empty the queue. Later calls queue again (up to 100) until the next `enable()`. */
disable(): void;
/** True once `enable()` has finished and until `disable()`. */
readonly enabled: boolean;
/** Add an adapter at runtime (after a consent choice, or lazily). */
use(adapter: AnalyticsAdapter): void;
/** Every adapter in use, in the order calls reach them. */
readonly adapters: readonly AnalyticsAdapter[];
}
The analytics service bound as analytics in the container and returned by useAnalytics().
Every call goes to each adapter, or waits in a queue until enable().
AnalyticsAdapter
interface AnalyticsAdapter {
/** Shown in devtools and in debug warnings, such as `google-analytics` or `plausible`. */
name: string;
/** Load scripts, create clients. Called once on the client when tracking is enabled. */
init?(): void | Promise<void>;
/** Record a page view for `path`; `props.url` and `props.title` carry the full URL and document title. */
page(path: string, props?: EventProps & {
url?: string;
title?: string;
}): void;
/** Record a named event with its props. */
track(event: string, props?: EventProps): void;
/** Attach later events to a user id. Optional; services without user profiles leave it out. */
identify?(userId: string, traits?: EventProps): void;
/** Forget the identified user, on sign-out. Optional. */
reset?(): void;
}
What every destination implements. Methods are best-effort and must never throw into app code.
AnalyticsConfig
interface AnalyticsConfig<E extends EventMap = EventMap> {
/** Where calls go. Empty in the provider means the console in development and nothing in production. */
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;
}
Options for config/analytics.ts and createAnalytics(). E is the app's event map.
PostHogLike
interface PostHogLike {
/** Start the client with a project API key and options. */
init(token: string, config?: Record<string, unknown>): unknown;
/** Send one event, `$pageview` included. */
capture(event: string, properties?: Record<string, unknown> | null): unknown;
/** Attach later events to a user id. */
identify(id?: string, properties?: Record<string, unknown>): void;
/** Forget the identified user. */
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>;
Props sent with an event, a page view or an identify call. Adapters pass them to the vendor as they are.
Track
type Track<E extends EventMap> = string extends keyof E ? (event: string, props?: EventProps) => void : <K extends keyof E & string>(event: K, ...props: E[K] extends undefined ? [
] : [
E[K]
]) => void;
track()'s signature: checked against the event map when there is one.
@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.