PostHog
Analytics wall-to-wall — web pageviews, wishlist funnel, game events
Analytics run on PostHog Cloud EU, project Being Human (216628). Both apps report
into the same project so the whole funnel — page view → wishlist → invite → achievement — lives
in one place.
Dashboard: Being Human — Launch (pageviews, wishlist growth, form failures, invites, achievement unlocks by key).
Web (apps/web)
components/analytics.tsx initialises posthog-js and captures a $pageview on every route
change. The wishlist form fires its own events and identifies the person by email on success.
| Event | When |
|---|---|
$pageview | every route change |
wishlist_signup | form submitted successfully (already_signed_up property) |
wishlist_signup_failed | form submit failed (message property) |
Configured via env (unset = analytics disabled, no errors):
# apps/web/.env.local
NEXT_PUBLIC_POSTHOG_KEY=phc_… # public project key — safe in the client
NEXT_PUBLIC_POSTHOG_HOST=https://eu.i.posthog.comAPI (apps/api)
src/analytics.ts is a fire-and-forget notifier (same contract as the Discord one): plain
fetch to PostHog's capture endpoint, never throws, never blocks a response, disabled without
POSTHOG_API_KEY.
| Event | Distinct ID | When |
|---|---|---|
wishlist_signup_recorded | new wishlist row inserted | |
invite_created | user id | invite code generated |
invite_claimed | invite claimed by email | |
invite_redeemed | user id | invite redeemed by an account |
achievement_unlocked | user id | first unlock (achievement_key property) |
# apps/api/.env
POSTHOG_API_KEY=phc_… # same project key
POSTHOG_HOST=https://eu.i.posthog.comAll server events carry source: "api" so they're easy to separate from client events.
Game events
The game (native or WASM shell) should not talk to PostHog directly — send gameplay milestones through this API (e.g. the achievements endpoint) and they get captured with the same distinct IDs as the website, keeping one identity per player across marketing site, account and game.