You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: context/commandments.yaml
+6-2Lines changed: 6 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -34,6 +34,7 @@ commandments:
34
34
# Server-side feature flags
35
35
- Server Components and Route Handlers cannot use React hooks - use posthog-node SDK instead
36
36
- Create a server-side PostHog client with posthog-node, call getAllFlags() or getFeatureFlag(), then await posthog.shutdown()
37
+
- 'Route Handlers and Server Actions are short-lived per request. Create the posthog-node client with flushAt 1 and flushInterval 0, and `await posthog.flush()` after capturing and before returning, or the function freezes before the event is sent and it is silently dropped'
37
38
- Pass flag values from server to client components as props to avoid hydration mismatches
38
39
# Avoiding flicker
39
40
- For flags that affect initial render, evaluate server-side and pass as props to prevent UI flicker
@@ -56,8 +57,8 @@ commandments:
56
57
- 'Include enableExceptionAutocapture: true in the PostHog constructor options'
57
58
- Add posthog.capture() calls in route handlers for meaningful user actions – every route that creates, updates, or deletes data should track an event with contextual properties
58
59
- Add posthog.captureException(err, distinctId) in the application's error handler (e.g., Express error middleware, Fastify setErrorHandler, Koa app.on('error'))
59
-
- In long-running servers, the SDK batches events automatically – do NOT set flushAt or flushInterval unless you have a specific reason to
60
-
- For short-lived processes (scripts, CLIs, serverless), set flushAt to 1 and flushInterval to 0 to send events immediately
60
+
- The SDK batches events and flushes asynchronously. await flush() or await shutdown() before letting that process exit. If unsure, set flushAt 1 and flushInterval 0.
61
+
- '`posthog.capture()` enqueues synchronously and returns; the batched HTTP send happens afterwards. Treat every per-request handler as short-lived even when the framework feels like a server: Next.js / Nuxt / SvelteKit / Remix route handlers, serverless and edge functions, and Lambda are torn down per invocation before the send runs. Create the client with flushAt 1 and flushInterval 0, then await the send before returning. Always use `await posthog.flush()` for a shared/singleton client, `await posthog.shutdown()` for a per-request client. Never skip the awaited flush or risk the enqueued event being silently dropped.'
61
62
- Reverse proxy is NOT needed for server-side Node.js – only client-side JavaScript needs a proxy to avoid ad blockers
62
63
63
64
python:
@@ -195,6 +196,7 @@ commandments:
195
196
- Test queries in the PostHog SQL editor before using them in insights or the API
196
197
197
198
sveltekit:
199
+
- 'For server-side capture (+server.ts endpoints, actions, hooks like handleError), the handler is short-lived per request. Configure the posthog-node singleton with flushAt 1 and flushInterval 0, and `await posthog.flush()` after capturing and before returning, or the batched event is silently dropped when the request ends'
198
200
- Set paths.relative to false in svelte.config.js — this is required for PostHog session replay to work correctly with SSR and is easy to miss
199
201
- Use the Svelte MCP server tools to check Svelte documentation (list-sections, get-documentation) and validate components (svelte-autofixer) — always run svelte-autofixer on new or modified .svelte files before finishing
200
202
@@ -254,11 +256,13 @@ commandments:
254
256
astro-ssr:
255
257
- Use posthog-node in API routes under src/pages/api/ for server-side event tracking
256
258
- Store the posthog-node client instance in a singleton pattern (src/lib/posthog-server.ts) to avoid creating multiple clients
259
+
- 'Configure the singleton with flushAt 1 and flushInterval 0, and `await posthog.flush()` in the API route after capturing and before returning the Response. An SSR endpoint is short-lived per request, so an unflushed batched event is silently dropped'
257
260
- Pass the client session ID to server via X-PostHog-Session-Id header for unified session tracking
258
261
259
262
astro-hybrid:
260
263
- Use posthog-node in API routes under src/pages/api/ for server-side event tracking
261
264
- Store the posthog-node client instance in a singleton pattern (src/lib/posthog-server.ts) to avoid creating multiple clients
265
+
- 'Configure the singleton with flushAt 1 and flushInterval 0, and `await posthog.flush()` in the API route after capturing and before returning the Response. An SSR endpoint is short-lived per request, so an unflushed batched event is silently dropped'
262
266
- In Astro 5, use output static (the default) with an adapter - pages are prerendered by default
263
267
- Use export const prerender = false to opt specific pages into SSR when they need server-side rendering
264
268
- Only pages that need server-side PostHog tracking (like API-backed forms) should opt out of prerendering
0 commit comments