Build apps with PostHog
PostHog is the analytics layer in every Goodspeed app: consent-aware lazy init, a typed EVENTS catalog, feature flags, and A/B testing. Goodspeed generates PostHog as a standard part of every app, so the output is a working codebase from day one, not a scaffold you have to finish yourself.
WHAT GETS GENERATED
Built into every PostHog build
Every app Goodspeed generates with PostHog includes these production-ready patterns, wired together from the first build.
| Item | Description | Strength |
|---|---|---|
| lib/posthog.ts consent-aware lazy init | The PostHog client is not created at module load time. getPostHog() initializes it on first call, but only if GDPR analytics consent has been granted. | Privacy |
| hooks/useAnalytics.ts custom event hook | A React hook that wraps captureEvent and captureScreen from lib/posthog.ts, making event tracking a one-liner in any component. | Hook |
| lib/events.ts typed EVENTS catalog | A string-literal-union EVENTS type exports every declared event name. TypeScript rejects any captureEvent call that uses an undeclared string. | Type Safety |
| gasConfig.backend.posthog keys | PostHog API key and host live in gas.config.ts under backend.posthog, read by lib/posthog.ts on first initialization. | Configuration |
| Feature flags and A/B testing | posthog.isFeatureEnabled and posthog.getFeatureFlag are called in hooks/useFeatureFlag.ts to gate features and split-test UI variants. | Experimentation |
Source: gas-template repository · Product Analytics
REAL GENERATED CODE
A snippet from a PostHog app the studio shipped
This pattern comes directly from the gas-template codebase, the foundation every Goodspeed app is generated on. The studio generates PostHog code like this for every app in the pipeline, not just a hello-world scaffold.
Consent-aware init
// lib/posthog.ts: lazy, consent-aware PostHog singleton let _posthog: PostHog | null = null; export async function getPostHog(): Promise<PostHog | null> { if (_posthog) return _posthog; const granted = await checkAnalyticsConsent(); if (!granted) return null; if (!apiKey) return null; _posthog = new PostHog(apiKey, { host, persistence: 'memory', bootstrap: { distinctId: await getAnonymousId() }, }); return _posthog; }
GDaily Allergens
Today's log
Gluten
Tree nuts
Shellfish
Dairy
HomeScanLogProfile