Built-in events
The complete catalog of analytics events the boilerplate fires on its own - client events from useAnalytics() and server events from payment webhooks, credit settlement, and auth hooks - with the properties each carries.
The conversion funnel fires automatically - add track calls only for product-specific events. Names follow GA4 recommended events; client events reach every enabled provider, server events PostHog only.
Client events
| Event | Fired when | Properties |
|---|---|---|
pricing_viewed | Pricing grid enters the viewport | source (marketing / billing) |
cta_clicked | Hero or navbar CTA click (data-analytics-event) | event, location |
signup_started | First interaction with a register form or social button | method |
sign_up | Account created (password, OAuth, magic link) | method |
login | Returning user signs in | method |
onboarding_started | Onboarding form mounts | - |
onboarding_completed | Onboarding form submitted | marketingOptIn |
begin_checkout | Checkout starts | type, planId / productId / credits, interval |
purchase | Checkout return (via trackRevenue) | amount, currency, orderId, type |
checkout_cancelled | Provider checkout abandoned | - |
search | Search results shown, once per query (no query text) | resultCount |
logout | Sign-out click | - |
not_found | Locale 404 page renders | path, referrer (both sanitized) |
error_boundary | Error boundary catches a render error | digest |
unsubscribed | Unsubscribe page confirms the opt-out | - |
waitlist_joined | Visitor joins the waitlist | - |
organization_created | Organization created | source (onboarding / settings) |
member_invited | Invitation sent | role |
invitation_accepted | Invitation accepted | - |
api_key_created | API key created | - |
newsletter_subscribed / newsletter_unsubscribed | Marketing-emails toggle changes | - |
contact_form_submitted | Contact form sent | - |
account_deleted | Account deletion confirmed | - |
ai_message_sent | Message sent to the AI chat | backend, hasAttachments |
ai_run_cancelled | AI run cancelled | backend |
- Redirect auth flows (OAuth, magic link) resolve after the redirect: accounts under 5 minutes old count as
sign_up, older ones aslogin. - Client events no-op when no provider is enabled.
Server events
Payment webhooks, credit settlement, and auth hooks emit through @repo/analytics. PostHog is the only server adapter today.
| Event | Fired from | Properties |
|---|---|---|
purchase | Stripe / Polar webhook | amount, currency, orderId, type (plan / product / credits), providerEventId |
subscription_started | webhook | planId, interval, trial |
subscription_renewed | webhook (where surfaced) | planId |
subscription_upgraded / subscription_downgraded | webhook | toPlanId, fromPlanId where present |
subscription_cancelled | webhook | planId, atPeriodEnd where present |
trial_started | webhook | planId |
refund | webhook (where surfaced) | amount, currency, orderId |
credits_consumed | Metered credits (AI usage, web tools) | amount, feature |
email_verified | Better Auth email verification | - |
group organization | Organization create | - |
- Emits never fail a webhook: try/catch-wrapped, fire-and-forget, and retry-safe - each uuid is seeded from
${claimId}:${eventName}, the webhook's own claim id.providerEventIdis apurchaseproperty only. purchasereaches PostHog twice by design: the client event feeds the client-only providers; the server event (providerEventId) is the revenue truth.- Honors
config.analytics.enableInDev.
Analytics
Wire one or more analytics providers through config.analytics, gate the cookie-dropping ones behind consent, and dispatch events with useAnalytics().
Pageviews and attribution
PostHog capture settings (SPA pageviews, page-leaves, dead clicks, web vitals) and first-touch attribution - the first_touch cookie, the user field it lands on, and the person properties it feeds.