Front-end analytics

Analytics

Chai's components report what people do and see in them, one event at a time, to the analytics tool you already use. One function, passed to each component, and nothing else to build.

Front end only

Events describe the person's actions and what the components showed them. No prompt text, file names, URLs or outputs are sent: only lengths, counts and Chai's own ids. Model calls, latency, cost and storage belong to your back end, where they're accurate.

Try it

Use the bar and the result cards below: pick a use case or a model, attach an image, enhance the prompt, talk to the mic, submit. Your events appear on the right as they fire, and go to this site's PostHog project with everyone else's, in the dashboard below. Results are placeholders that take a few seconds, so there's time to click Stop: the docs make no model calls.

Image
Your events0

None yet. Pick a model, type a prompt and submit.

The next runs end in an error, so you can see chai_result_shown with status: error and try Retry.

Analytics Dashboard

The same events from every visitor to these previews, charted by PostHog. It refreshes every 30 minutes, so your clicks show up here on the next refresh.

Open the dashboard in PostHog

Set it up

PostHog is the example; any tool's capture call works the same way. Initialize your tool once, write one track function, and pass it to each Chai component as onEvent (@event in Vue). Cookieless mode needs no consent banner; turn on cookieless tracking in your PostHog project too.

import posthog from "posthog-js";
import { Composer, ResultCard, useComposer, type ChaiEvent } from "@chai-ui/react";
import { useState } from "react";
// Once, at your app's entry point. Cookieless: no cookies, no banner.
posthog.init("<your PostHog project token>", {
api_host: "https://us.i.posthog.com",
cookieless_mode: "always",
});
// One function for every Chai component.
const track = (e: ChaiEvent) => posthog.capture(e.name, e.properties);
export function Create() {
const [value, setValue] = useState("");
const { runs, submit } = useComposer();
return (
<>
<Composer value={value} onChange={setValue} onSubmit={submit} onEvent={track} />
{runs.map((run) => (
<ResultCard key={run.id} results={run.results} prompt={run.request.prompt} onAction={() => {}} onEvent={track} />
))}
</>
);
}

To keep ad blockers from dropping events, send them through your own domain with a reverse proxy, as PostHog's guides describe. See also Develop for the rest of the setup.

The events

EventFires when the person…Properties
chai_composer_submittedsubmitsuse_cases, model_count, auto_select, aspect_ratio, attachment_count, prompt_length, retry
chai_composer_stoppedclicks Stopnone
chai_composer_use_case_pickedpicks a + menu itemaction
chai_composer_use_case_removedremoves a use-case chipuse_case
chai_composer_media_attachedadds filescount, unsupported_count
chai_composer_model_pickedpicks a modeluse_case, model_id
chai_composer_auto_select_toggledflips auto-selecton
chai_composer_option_pickedpicks an aspect ratio, voice, genre or frame rateoption, value
chai_composer_enhance_clickedclicks Enhancefield, prompt_length
chai_composer_enhance_revertedreverts an Enhance to the originalfield
chai_composer_voice_startedstarts voice inputnone
chai_result_shownsees a result or an error appear (once each)status, output_kind, result_count
chai_result_actionlikes, downloads, shares, copies or retriesaction
chai_result_pagedpages to another resultindex, count
chai_result_info_openedopens a result's detailsnone

Build the dashboard

Chai's events are ordinary events in your analytics tool, so its own dashboards chart them. In PostHog, build each chart below as an insight on one dashboard, by hand or through PostHog's API. To show it in your own app, turn on the dashboard's public sharing and embed the link in an iframe.

Building through the API needs a personal API key (phx_…), scoped to the project with insight, dashboard and sharing write access. Keep it on your server or your machine: unlike the project token, it reads and changes your data, so it never goes in the browser or in a VITE_ or NEXT_PUBLIC_ variable.

ChartEventsBreakdown or filter
Most used UI elementsevery chai_ event but chai_result_shownUI element, 30-day total
Submitschai_composer_submittedper day
Use case mixchai_composer_submitteduse_cases
Model pickschai_composer_model_pickedmodel_id
Funnel: submitted, shown, downloadedchai_composer_submittedchai_result_shownchai_result_actionstatus done, action download
Enhance and voice inputchai_composer_enhance_clickedchai_composer_voice_startedper day

The script that builds this site's dashboard does all of it: it creates each chart at its size, swaps in new charts on every run while keeping the dashboard (so the embed link never changes), turns on sharing and prints the URL to embed. Run it with Node 20 or later, with your key and project ID in an env file.

posthog-dashboard.mjs

Every chart counts events; none follows a person. That fits cookieless tracking, where PostHog can't tell one visitor's sessions apart over days.

What Chai doesn't track

Model call success and latency, tokens, cost, and generated files stored: these happen on your server and at your providers (Fal.ai, OpenRouter), which report them accurately. Chai covers the front end only.