TL;DR — Sign up for PostHog Cloud → drop in
posthog-js
→ wire up server‑side events → build Retention & Funnel dashboards → sketch a Feature‑Flag A/B test — all in 24 hours. The game still sits at 0 % Day‑1 retention; this post is about getting ready to fix it, not claiming victory.
0. Context
- Indie web game “lamma vs duck” launched with ~100 unique visitors and a flat 0 % Day‑1 retention. We need hard data before we guess why.
- Requirements: free tier, GDPR‑/Korea‑compliant, real‑time cohorts.
PostHog Cloud (Free tier) + Next.js SDK + Supabase server API hit the sweet spot for speed and cost.
1. Create a PostHog Cloud project (10 min)
- Sign up at https://posthog.com → Create New Project.
- Copy your
project‑key
, choose the EU data center (Seoul↔EU RTT ≈ 300 ms). - Toggle Autocapture OFF to keep noise low from day 1.
2. Capture client‑side events in Next.js (15 min)
npm i posthog-js
// utils/posthog.ts
import posthog from 'posthog-js';
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
api_host: 'https://app.posthog.com',
loaded: (ph) => {
if (process.env.NODE_ENV === 'development') ph.debug();
},
});
export default posthog;
Wrap game‑specific events:
export const trackGameEvent = (
name: 'start' | 'finish' | 'share',
props: Record<string, unknown> = {},
) => posthog.capture(`game_${name}`, props);
3. Server‑side events & Supabase RLS (20 min)
Why? Guest sessions alone break cohort analysis. We attach a stable
distinct_id
on the server.
// app/api/score/route.ts
import { createClient } from '@/lib/supabase';
import posthog from '@/utils/posthog-server';
...
const { user } = await createClient();
await posthog.capture({
distinctId: user?.id ?? sessionId, // anonymous vs logged‑in
event: 'score_submit',
properties: { score, level, device: ua.device.type },
});
- Keep the secret key secret:
.env → NEXT_PRIVATE_POSTHOG_KEY
. - Supabase RLS: allow
insert
only for service role; PostHog callback timeout <= 3 s.
4. Build Retention & Funnel dashboards (10 min)
-
Event definitions:
game_start
,game_finish
,score_submit
,session_signup
, … -
Retention insight: First time
game_start
→ returninggame_start
, window 7 days. -
Funnel:
landing_view
→game_start
→game_finish
. - Pin charts to dashboard “Lamma Game Health”.
5. Draft a Feature‑Flag A/B test (5 min)
-
Flag:
show_fake_leaderboard
- Variant A: inject 10 fake high scores.
- Variant B: real scores only.
- Planned traffic split 70 % / 30 %.
const fakeLeaderboardOn = useFeatureFlag('show_fake_leaderboard');
The experiment is scheduled but not yet running. Results will follow in a future post.
6. Baseline metrics (actual data)
Metric | Value |
---|---|
Day‑1 Retention | 0 % |
Funnel Completion (Landing → Game Start) | 18 % |
Avg. Session Length | 1 min 12 s |
These numbers are the starting line, not the finish line.
7. Lessons learned & next steps
- Design your events first — capture only what matters.
-
Server events + consistent
distinct_id
are mandatory for reliable cohorts. - PostHog Feature Flags are good enough for lightweight UI experiments.
- Pipe raw events to Supabase → Metabase later for deeper BI.
🦙 Play “lamma vs duck” & help us fix retention!
https://lamma-vs-duck.vercel.app (guest mode available). Your session will feed the baseline dataset — thank you!
Thanks for reading! Questions or feedback? Drop a comment here 🚀
Top comments (0)