User Analytics
Kit ships no analytics - by design. Pick a tool when you have users; here's how the pieces slot in.
Start: Vercel Analytics
Zero-config traffic and Web Vitals if you deploy to Vercel:
pnpm -F @repo/web add @vercel/analytics// apps/web/src/app/layout.tsx
import { Analytics } from "@vercel/analytics/react";
// Render inside <body>
<Analytics />;Covers "is anyone visiting" and "is it fast". It won't tell you what users do.
Product Analytics: PostHog
When you need funnels, retention, and feature usage:
pnpm -F @repo/web add posthog-jsInitialize in a client provider (next to TRPCReactProvider in apps/web/src/app/layout.tsx), then identify against the entities Kit already has - user and organization:
import posthog from "posthog-js";
import { authClient } from "@/lib/auth-client";
const { data: session } = authClient.useSession();
if (session) {
posthog.identify(session.user.id);
// Group by tenant, matching the org-scoped data model
posthog.group("organization", organization.id);
}Grouping by organization matters more than individual users in a multi-tenant app - "which workspaces are active" is the retention question.
What to Track
Instrument the loops Kit ships, not everything:
- Activation - signup → first org action (first todo, first invite)
- Waitlist conversion -
waitlist.joinfires → how many become users? Thewaitlisttable already stores email +userIdfor the join - Invites - sent vs. accepted (the
invitationtable holds state) - AI chat usage - messages per org; this is also your cost driver
Server-Side Events
For events you can't trust the client to report, a tRPC middleware sees every procedure call:
// packages/api/src/trpc.ts
const analyticsMiddleware = t.middleware(async ({ next, path, type, ctx }) => {
const result = await next();
if (type === "mutation" && result.ok) {
// capture(ctx.session?.user.id, path)
}
return result;
});Keep it fire-and-forget - analytics must never fail a request.
Privacy
- Track ids, not emails -
user.idis enough to join against your database later robots.txtalready declares AI-usage signals (Content-Signal); add a privacy policy before adding trackers- EU users? Prefer server-side capture or a cookieless config
Next Steps
- Feedback - Qualitative signal
- Growth - Acting on the numbers