vybekiit 0.7.3 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +16607 -7527
- package/dist/global-skills/aws-cdk/SKILL.md +2 -1
- package/dist/global-skills/aws-cloudformation/SKILL.md +2 -1
- package/dist/global-skills/aws-serverless/SKILL.md +45 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +2 -1
- package/dist/global-skills/aws-serverless/references/api-gateway.md +50 -470
- package/dist/global-skills/aws-serverless/references/architecture.md +47 -186
- package/dist/global-skills/aws-serverless/references/concurrency.md +44 -158
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +72 -391
- package/dist/global-skills/aws-serverless/references/lambda.md +69 -428
- package/dist/global-skills/aws-serverless/references/orchestration.md +65 -384
- package/dist/global-skills/aws-serverless/references/production.md +78 -415
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +92 -619
- package/dist/global-skills/claimable-postgres/SKILL.md +60 -49
- package/dist/global-skills/design-my-data/SKILL.md +2 -0
- package/dist/global-skills/eas-app-stores/SKILL.md +8 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +2 -0
- package/dist/global-skills/eas-hosting/SKILL.md +8 -0
- package/dist/global-skills/eas-observe/SKILL.md +30 -8
- package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-observe/references/metrics.md +54 -3
- package/dist/global-skills/eas-observe/references/queries.md +78 -17
- package/dist/global-skills/eas-observe/references/setup.md +164 -5
- package/dist/global-skills/eas-observe/references/third-party.md +136 -0
- package/dist/global-skills/eas-simulator/SKILL.md +63 -11
- package/dist/global-skills/eas-simulator/references/controllers.md +21 -2
- package/dist/global-skills/eas-simulator/references/run-your-app.md +16 -11
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -5
- package/dist/global-skills/eas-update-insights/SKILL.md +8 -0
- package/dist/global-skills/eas-workflows/SKILL.md +15 -10
- package/dist/global-skills/eas-workflows/scripts/package.json +2 -7
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +30 -0
- package/dist/global-skills/email-best-practices/README.md +63 -0
- package/dist/global-skills/email-best-practices/references/accessibility.md +189 -0
- package/dist/global-skills/email-best-practices/references/compliance.md +125 -0
- package/dist/global-skills/email-best-practices/references/deliverability.md +121 -0
- package/dist/global-skills/email-best-practices/references/email-capture.md +129 -0
- package/dist/global-skills/email-best-practices/references/email-types.md +173 -0
- package/dist/global-skills/email-best-practices/references/list-management.md +157 -0
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +115 -0
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +155 -0
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +418 -0
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +92 -0
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +167 -0
- package/dist/global-skills/email-best-practices/tests/README.md +35 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +46 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +48 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +36 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +52 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +51 -0
- package/dist/global-skills/expo-animation/LICENSE +21 -0
- package/dist/global-skills/expo-animation/RECIPES.md +385 -0
- package/dist/global-skills/expo-animation/SKILL.md +267 -0
- package/dist/global-skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +53 -4
- package/dist/global-skills/expo-data-fetching/SKILL.md +8 -0
- package/dist/global-skills/expo-design-system/SKILL.md +356 -0
- package/dist/global-skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-design-system/references/audit.md +185 -0
- package/dist/global-skills/expo-dev-client/SKILL.md +8 -0
- package/dist/global-skills/expo-dom/SKILL.md +8 -0
- package/dist/global-skills/expo-examples/SKILL.md +8 -0
- package/dist/global-skills/expo-migrate-module/SKILL.md +113 -0
- package/dist/global-skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +73 -0
- package/dist/global-skills/expo-migrate-module/references/example.md +212 -0
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +306 -0
- package/dist/global-skills/expo-module/SKILL.md +11 -1
- package/dist/global-skills/expo-native-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-project-structure/SKILL.md +114 -0
- package/dist/global-skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-router/SKILL.md +8 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +66 -33
- package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +8 -0
- package/dist/global-skills/expo-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-upgrade/SKILL.md +15 -1
- package/dist/global-skills/expo-web-to-native/SKILL.md +8 -0
- package/dist/global-skills/extension-to-functions-codebase/SKILL.md +129 -0
- package/dist/global-skills/extension-to-functions-codebase/references/configuration-migration.md +161 -0
- package/dist/global-skills/extension-to-functions-codebase/references/destructuring-shim.md +122 -0
- package/dist/global-skills/extension-to-functions-codebase/references/signature-mapping.md +84 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +61 -19
- package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +6 -3
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-auth-basics/SKILL.md +4 -2
- package/dist/global-skills/firebase-basics/SKILL.md +5 -5
- package/dist/global-skills/firebase-crashlytics/SKILL.md +2 -0
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -0
- package/dist/global-skills/firebase-firestore/SKILL.md +3 -6
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +4 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +4 -1
- package/dist/global-skills/harden/SKILL.md +2 -1
- package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
- package/dist/global-skills/instrument-feature-flags/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/api.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/django.md +38 -5
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/flask.md +17 -5
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +7 -5
- package/dist/global-skills/instrument-feature-flags/references/go.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ios.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/java.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +74 -8
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/php.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/python.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/rust.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/usage.md +41 -4
- package/dist/global-skills/instrument-feature-flags/references/web.md +7 -5
- package/dist/global-skills/instrument-product-analytics/SKILL.md +2 -1
- package/dist/global-skills/instrument-product-analytics/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +12 -14
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +25 -21
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +75 -55
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +3 -6
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +26 -16
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +8 -5
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +4 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +3 -3
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +8 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +20 -8
- package/dist/global-skills/instrument-product-analytics/references/android.md +46 -4
- package/dist/global-skills/instrument-product-analytics/references/angular.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/astro.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +7 -4
- package/dist/global-skills/instrument-product-analytics/references/django.md +38 -5
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/flask.md +17 -5
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +49 -4
- package/dist/global-skills/instrument-product-analytics/references/go.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +38 -7
- package/dist/global-skills/instrument-product-analytics/references/ios.md +14 -4
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +74 -8
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +39 -7
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +40 -4
- package/dist/global-skills/instrument-product-analytics/references/php.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +21 -17
- package/dist/global-skills/instrument-product-analytics/references/python.md +15 -5
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +41 -7
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +42 -6
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +31 -7
- package/dist/global-skills/instrument-product-analytics/references/usage.md +41 -4
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +42 -6
- package/dist/global-skills/manifest.json +6 -1
- package/dist/global-skills/neon/SKILL.md +235 -121
- package/dist/global-skills/neon-ai-gateway/SKILL.md +95 -16
- package/dist/global-skills/neon-functions/SKILL.md +242 -152
- package/dist/global-skills/neon-functions/references/ai-sdk.md +9 -3
- package/dist/global-skills/neon-functions/references/mastra-studio.md +1 -1
- package/dist/global-skills/neon-functions/references/mcp.md +13 -4
- package/dist/global-skills/neon-functions/references/sentry.md +165 -52
- package/dist/global-skills/neon-functions/references/sse.md +23 -6
- package/dist/global-skills/neon-object-storage/SKILL.md +40 -16
- package/dist/global-skills/neon-postgres/SKILL.md +63 -262
- package/dist/global-skills/neon-postgres-branches/SKILL.md +61 -50
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +22 -3
- package/dist/global-skills/resend/SKILL.md +6 -6
- package/dist/global-skills/resend/references/automations.md +2 -2
- package/dist/global-skills/resend/references/broadcasts.md +11 -3
- package/dist/global-skills/resend/references/domains.md +25 -3
- package/dist/global-skills/resend/references/installation.md +7 -7
- package/dist/global-skills/setup-payments/SKILL.md +4 -5
- package/dist/global-skills/stripe-best-practices/SKILL.md +32 -7
- package/dist/global-skills/stripe-best-practices/references/billing.md +11 -1
- package/dist/global-skills/stripe-best-practices/references/payments.md +23 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +21 -11
- package/dist/global-skills/stripe-best-practices/references/tax.md +116 -11
- package/dist/global-skills/supabase/CHANGELOG.md +25 -0
- package/dist/global-skills/supabase/SKILL.md +5 -1
- package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +30 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -1
- package/dist/global-skills/use-kit-mcp/SKILL.md +5 -5
- package/dist/global-skills/use-railway/SKILL.md +4 -4
- package/dist/global-skills/use-railway/references/iac.md +206 -57
- package/dist/global-skills/use-railway/scripts/railway-api.sh +7 -2
- package/dist/global-skills/xcode-project-setup/SKILL.md +2 -0
- package/package.json +12 -9
- package/LICENSE.md +0 -47
- package/dist/global-skills/eas-workflows/scripts/validate.js +0 -84
- package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +0 -118
- package/dist/global-skills/neon-functions/references/hono-websockets.md +0 -145
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# Next.js - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# Next.js - Docs
|
|
2
8
|
|
|
3
9
|
PostHog makes it easy to get data about traffic and usage of your [Next.js](https://nextjs.org/) app. Integrating PostHog into your site enables analytics about user behavior, custom events capture, session recordings, feature flags, and more.
|
|
@@ -57,6 +63,18 @@ pnpm add posthog-js
|
|
|
57
63
|
bun add posthog-js
|
|
58
64
|
```
|
|
59
65
|
|
|
66
|
+
> **If your site sets a Content-Security-Policy**, it needs to allow PostHog. This applies to the snippet and to package installs alike: the SDK lazy-loads extra bundles (session replay, surveys) from PostHog's CDN, and sends events to the ingestion host. PostHog serves from subdomains of `posthog.com` that change over time, so allow the wildcard:
|
|
67
|
+
>
|
|
68
|
+
> PostHog AI
|
|
69
|
+
>
|
|
70
|
+
> ```
|
|
71
|
+
> script-src 'self' https://*.posthog.com;
|
|
72
|
+
> connect-src 'self' https://*.posthog.com;
|
|
73
|
+
> worker-src 'self' blob: data:;
|
|
74
|
+
> ```
|
|
75
|
+
>
|
|
76
|
+
> `script-src` covers the snippet and the lazy-loaded bundles, `connect-src` covers event ingestion and feature flags, and `worker-src` covers session replay. The [toolbar needs a few more](/docs/advanced/content-security-policy.md), or use a [reverse proxy](/docs/advanced/proxy.md) so everything is first-party. Failing to do so causes silent failures where `capture` and `identify` calls never send, so the integration looks complete while zero events arrive. Remember `connect-src` falls back to `default-src`, so `default-src 'self'` blocks event delivery even when the script itself is bundled.
|
|
77
|
+
|
|
60
78
|
Add your environment variables to your `.env.local` file and to your hosting provider (e.g. Vercel, Netlify, AWS). You can find your project token in your [project settings](https://app.posthog.com/project/settings).
|
|
61
79
|
|
|
62
80
|
.env.local
|
|
@@ -113,8 +131,34 @@ See the [bootstrapping guide](/docs/feature-flags/bootstrapping.md) for more inf
|
|
|
113
131
|
|
|
114
132
|
> **Identifying users is required.** Call `posthog.identify('your-user-id')` after login to link events to a known user. This is what connects frontend event captures, [session replays](/docs/session-replay.md), [LLM traces](/docs/ai-engineering.md), and [error tracking](/docs/error-tracking.md) to the same person — and lets backend events link back too.
|
|
115
133
|
>
|
|
134
|
+
> Use a stable ID from your auth system when possible, not an email or display name. Send those as person properties instead. If your app has no other stable key, email works as a fallback if they are unique. Never a shared literal like `"anonymous"` or `"user"`, which pools many people onto one person and corrupts their data. When no ID is available at all, skip the identify and retain the anonymous distinct ID that's automatically assigned.
|
|
135
|
+
>
|
|
136
|
+
> Call `posthog.reset()` on logout, so the next person to use the browser doesn't inherit the last one's identity.
|
|
137
|
+
>
|
|
116
138
|
> See our guide on [identifying users](/docs/getting-started/identify-users.md) for how to set this up.
|
|
117
139
|
|
|
140
|
+
### Linking client and server events
|
|
141
|
+
|
|
142
|
+
Next.js apps usually capture on both sides. To keep them on the same person, use the same distinct ID in both, and let the browser tell your server which one that is.
|
|
143
|
+
|
|
144
|
+
If your app calls your own backend, `tracing_headers` adds `X-POSTHOG-DISTINCT-ID` and `X-POSTHOG-SESSION-ID` to matching `fetch` and `XMLHttpRequest` requests. This lets server-side SDKs link backend events, errors, and LLM traces back to frontend sessions and replays. Use hostnames only, without protocols or paths.
|
|
145
|
+
|
|
146
|
+
JavaScript
|
|
147
|
+
|
|
148
|
+
PostHog AI
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
posthog.init('<ph_project_token>', {
|
|
152
|
+
api_host: 'https://us.i.posthog.com',
|
|
153
|
+
// Optional: send PostHog session/user context to your backend
|
|
154
|
+
tracing_headers: ['api.example.com'],
|
|
155
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
This works in local development too, but match on the hostname alone: use `'localhost'`, not `'localhost:3000'`. Ports are never part of a hostname, so a value with one in it never matches anything. `localhost` and `127.0.0.1` are also different hostnames — use whichever your app actually calls.
|
|
159
|
+
|
|
160
|
+
Tracing headers help you attribute events across front and backend consistently. When this isn't available, use your server-side stable IDs to deduce the matching `distinctId`, and pass it in when capturing the event.
|
|
161
|
+
|
|
118
162
|
Set up a reverse proxy (recommended)
|
|
119
163
|
|
|
120
164
|
We recommend [setting up a reverse proxy](/docs/advanced/proxy.md), so that events are less likely to be intercepted by tracking blockers.
|
|
@@ -183,7 +227,7 @@ See the [React SDK docs](/docs/libraries/react.md) for examples of how to use:
|
|
|
183
227
|
- [`posthog-js` functions like custom event capture, user identification, and more.](/docs/libraries/react.md#using-posthog-js-functions)
|
|
184
228
|
- [Feature flags including variants and payloads.](/docs/libraries/react.md#feature-flags)
|
|
185
229
|
|
|
186
|
-
You can also read [the full `posthog-js` documentation](/docs/libraries/js/
|
|
230
|
+
You can also read [the full `posthog-js` documentation](/docs/libraries/js/usage.md) for all the usable functions.
|
|
187
231
|
|
|
188
232
|
## Server-side analytics
|
|
189
233
|
|
|
@@ -288,6 +332,7 @@ PostHog AI
|
|
|
288
332
|
// pages/posts/[id].js
|
|
289
333
|
import { useContext, useEffect, useState } from 'react'
|
|
290
334
|
import { getServerSession } from "next-auth/next"
|
|
335
|
+
import { authOptions } from '@/lib/auth'
|
|
291
336
|
import { PostHog } from 'posthog-node'
|
|
292
337
|
export default function Post({ post, flags }) {
|
|
293
338
|
const [ctaState, setCtaState] = useState()
|
|
@@ -309,7 +354,8 @@ export default function Post({ post, flags }) {
|
|
|
309
354
|
)
|
|
310
355
|
}
|
|
311
356
|
export async function getServerSideProps(ctx) {
|
|
312
|
-
|
|
357
|
+
// Pass authOptions, or your session callbacks don't run.
|
|
358
|
+
const session = await getServerSession(ctx.req, ctx.res, authOptions)
|
|
313
359
|
let flags = null
|
|
314
360
|
if (session) {
|
|
315
361
|
const client = new PostHog(
|
|
@@ -318,9 +364,11 @@ export async function getServerSideProps(ctx) {
|
|
|
318
364
|
host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
|
|
319
365
|
}
|
|
320
366
|
)
|
|
321
|
-
|
|
367
|
+
// A stable ID from your auth system, not an email. See the note below.
|
|
368
|
+
const distinctId = session.user.id
|
|
369
|
+
flags = await client.getAllFlags(distinctId);
|
|
322
370
|
client.capture({
|
|
323
|
-
distinctId
|
|
371
|
+
distinctId,
|
|
324
372
|
event: 'loaded blog article',
|
|
325
373
|
properties: {
|
|
326
374
|
$current_url: ctx.req.url,
|
|
@@ -339,6 +387,28 @@ export async function getServerSideProps(ctx) {
|
|
|
339
387
|
}
|
|
340
388
|
```
|
|
341
389
|
|
|
390
|
+
> **Note**: next-auth doesn't put a user ID on the session by default. Its session is `{ name, email, image }`, so `session.user.id` is `undefined` until you add it yourself with a session callback in your `authOptions`:
|
|
391
|
+
>
|
|
392
|
+
> JavaScript
|
|
393
|
+
>
|
|
394
|
+
> PostHog AI
|
|
395
|
+
>
|
|
396
|
+
> ```javascript
|
|
397
|
+
> // lib/auth.js
|
|
398
|
+
> export const authOptions = {
|
|
399
|
+
> callbacks: {
|
|
400
|
+
> session({ session, token, user }) {
|
|
401
|
+
> // JWT sessions (the default) carry the user ID in token.sub.
|
|
402
|
+
> // Database sessions get it from user.id instead.
|
|
403
|
+
> session.user.id = token?.sub ?? user.id
|
|
404
|
+
> return session
|
|
405
|
+
> },
|
|
406
|
+
> },
|
|
407
|
+
> }
|
|
408
|
+
> ```
|
|
409
|
+
>
|
|
410
|
+
> Capturing with an `undefined` distinct ID creates events that belong to nobody, so check that the ID arrives before relying on it.
|
|
411
|
+
|
|
342
412
|
> **Note**: Make sure to *always* call `await client.shutdown()` after sending events from the server-side. PostHog queues events into larger batches, and this call forces all batched events to be flushed immediately.
|
|
343
413
|
|
|
344
414
|
### Server-side configuration
|
|
@@ -374,10 +444,6 @@ To improve the reliability of client-side tracking and make requests less likely
|
|
|
374
444
|
- [How to set up Next.js pages router analytics, feature flags, and more](/tutorials/nextjs-pages-analytics.md)
|
|
375
445
|
- [How to set up Next.js A/B tests](/tutorials/nextjs-ab-tests.md)
|
|
376
446
|
|
|
377
|
-
### Community questions
|
|
378
|
-
|
|
379
|
-
Ask a question
|
|
380
|
-
|
|
381
447
|
### Was this page useful?
|
|
382
448
|
|
|
383
449
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# Node.js Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# Node.js Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
1. 1
|
|
@@ -207,10 +213,6 @@
|
|
|
207
213
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
208
214
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
209
215
|
|
|
210
|
-
### Community questions
|
|
211
|
-
|
|
212
|
-
Ask a question
|
|
213
|
-
|
|
214
216
|
### Was this page useful?
|
|
215
217
|
|
|
216
218
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# PHP Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# PHP Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
1. 1
|
|
@@ -178,10 +184,6 @@
|
|
|
178
184
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
179
185
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
180
186
|
|
|
181
|
-
### Community questions
|
|
182
|
-
|
|
183
|
-
Ask a question
|
|
184
|
-
|
|
185
187
|
### Was this page useful?
|
|
186
188
|
|
|
187
189
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# Python Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# Python Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
1. 1
|
|
@@ -182,10 +188,6 @@
|
|
|
182
188
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
183
189
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
184
190
|
|
|
185
|
-
### Community questions
|
|
186
|
-
|
|
187
|
-
Ask a question
|
|
188
|
-
|
|
189
191
|
### Was this page useful?
|
|
190
192
|
|
|
191
193
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# React Native Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# React Native Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
1. 1
|
|
@@ -157,10 +163,6 @@
|
|
|
157
163
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
158
164
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
159
165
|
|
|
160
|
-
### Community questions
|
|
161
|
-
|
|
162
|
-
Ask a question
|
|
163
|
-
|
|
164
166
|
### Was this page useful?
|
|
165
167
|
|
|
166
168
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# React Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# React Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
1. 1
|
|
@@ -293,10 +299,6 @@
|
|
|
293
299
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
294
300
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
295
301
|
|
|
296
|
-
### Community questions
|
|
297
|
-
|
|
298
|
-
Ask a question
|
|
299
|
-
|
|
300
302
|
### Was this page useful?
|
|
301
303
|
|
|
302
304
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# Ruby on Rails - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# Ruby on Rails - Docs
|
|
2
8
|
|
|
3
9
|
PostHog makes it easy to get data about traffic and usage of your Ruby on Rails app. Integrating PostHog enables analytics, custom event capture, feature flags, and automatic exception tracking.
|
|
@@ -595,10 +601,6 @@ Ensure you've set `personal_api_key` in your configuration.
|
|
|
595
601
|
|
|
596
602
|
For any technical questions for how to integrate specific PostHog features into Rails (such as analytics, feature flags, A/B testing, etc.), have a look at our [Ruby SDK docs](/docs/libraries/ruby.md).
|
|
597
603
|
|
|
598
|
-
### Community questions
|
|
599
|
-
|
|
600
|
-
Ask a question
|
|
601
|
-
|
|
602
604
|
### Was this page useful?
|
|
603
605
|
|
|
604
606
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# Ruby Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# Ruby Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
1. 1
|
|
@@ -191,10 +197,6 @@
|
|
|
191
197
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
192
198
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
193
199
|
|
|
194
|
-
### Community questions
|
|
195
|
-
|
|
196
|
-
Ask a question
|
|
197
|
-
|
|
198
200
|
### Was this page useful?
|
|
199
201
|
|
|
200
202
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# Rust Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# Rust Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
Install the `posthog-rs` crate by adding it to your `Cargo.toml`.
|
|
@@ -213,10 +219,6 @@ Now that you're evaluating flags, continue with the resources below to learn wha
|
|
|
213
219
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
214
220
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
215
221
|
|
|
216
|
-
### Community questions
|
|
217
|
-
|
|
218
|
-
Ask a question
|
|
219
|
-
|
|
220
222
|
### Was this page useful?
|
|
221
223
|
|
|
222
224
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# iOS SDK usage - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# iOS SDK usage - Docs
|
|
2
8
|
|
|
3
9
|
## Capturing events
|
|
@@ -534,6 +540,41 @@ PostHogSDK.shared.captureFeatureView(flag: "flag-key", flagVariant: "variant-key
|
|
|
534
540
|
PostHogSDK.shared.captureFeatureInteraction(flag: "flag-key", flagVariant: "variant-key")
|
|
535
541
|
```
|
|
536
542
|
|
|
543
|
+
### Bootstrapping flags
|
|
544
|
+
|
|
545
|
+
Since there is a delay between initializing PostHog and fetching feature flags, feature flags are not always available immediately. This makes them unusable if you want to do something like redirecting a user to a different page based on a feature flag.
|
|
546
|
+
|
|
547
|
+
To have your feature flags available immediately, you can initialize PostHog with precomputed values until it has had a chance to fetch them. This is called bootstrapping. After the SDK fetches feature flags from PostHog, it will use those flag values instead of bootstrapped ones.
|
|
548
|
+
|
|
549
|
+
Set `config.bootstrap` before calling `setup()` to seed identity and flag values before the first `/flags` response (requires iOS SDK `3.66.0`+):
|
|
550
|
+
|
|
551
|
+
Swift
|
|
552
|
+
|
|
553
|
+
PostHog AI
|
|
554
|
+
|
|
555
|
+
```swift
|
|
556
|
+
let config = PostHogConfig(projectToken: "<ph_project_token>", host: "https://us.i.posthog.com")
|
|
557
|
+
config.bootstrap = PostHogBootstrapConfig(
|
|
558
|
+
distinctId: "distinct_id_of_your_user",
|
|
559
|
+
isIdentifiedId: true,
|
|
560
|
+
featureFlags: [
|
|
561
|
+
"flag-1": true,
|
|
562
|
+
"variant-flag": "control"
|
|
563
|
+
],
|
|
564
|
+
featureFlagPayloads: nil
|
|
565
|
+
)
|
|
566
|
+
PostHogSDK.shared.setup(config)
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
- **Bootstrapped identity applies during setup.** On a fresh install, setting it before `setup()` means events captured synchronously during initialization (like `Application Installed`) carry your distinct ID instead of the SDK-generated UUID.
|
|
570
|
+
- An **anonymous** bootstrap (`isIdentifiedId: false`, the default) seeds the anonymous ID only when none is persisted yet. Once an anonymous ID exists on disk, or the person has been identified, the SDK ignores it.
|
|
571
|
+
- An **identified** bootstrap (`isIdentifiedId: true`) is for a signed-in identity available to your app (for example, from a backend session token). On a fresh install, it seeds the distinct ID, marks the person identified, and generates a separate device ID. On a returning install, a matching anonymous ID is marked identified without emitting `$identify`; a different anonymous ID is merged via `identify()` when person profiles are enabled. This emits `$identify` unless capturing is opted out. A different, already-identified person is left untouched.
|
|
572
|
+
- **Bootstrapped flags are served until the first `/flags` response, then replaced.** A complete `/flags` response takes over entirely, so bootstrapped-only keys don't persist past it. Only *enabled* flags are seeded: a `true` boolean or a non-empty variant string. A `false` or empty value is dropped, matching posthog-js. Seed payloads with the separate `featureFlagPayloads` option. Flag values and payloads must be JSON-serializable, or they're dropped. Bootstrapped flags are cleared on `reset()`.
|
|
573
|
+
|
|
574
|
+
The feature-flags-loaded signal fires as soon as bootstrapped flags are applied, so startup logic can read them immediately. These SDKs don't support the `sessionID` bootstrap option. When person profiles are set to `never`, the SDK preserves a different anonymous identity instead of merging it into an identified bootstrap.
|
|
575
|
+
|
|
576
|
+
See the [SDK bootstrapping guide](/docs/libraries/bootstrapping.md) for the cross-SDK overview.
|
|
577
|
+
|
|
537
578
|
## Experiments (A/B tests)
|
|
538
579
|
|
|
539
580
|
Since [experiments](/docs/experiments/start-here.md) use feature flags, the code for running an experiment is very similar to the feature flags code. See [adding experiment code](/docs/experiments/adding-experiment-code.md) for iOS examples.
|
|
@@ -591,10 +632,6 @@ PostHogSDK.shared.debug(true)
|
|
|
591
632
|
PostHogSDK.shared.debug(false)
|
|
592
633
|
```
|
|
593
634
|
|
|
594
|
-
### Community questions
|
|
595
|
-
|
|
596
|
-
Ask a question
|
|
597
|
-
|
|
598
635
|
### Was this page useful?
|
|
599
636
|
|
|
600
637
|
HelpfulCould be better
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt
|
|
2
|
+
|
|
3
|
+
# Web Feature Flags installation - Docs
|
|
4
|
+
|
|
5
|
+
Copy page
|
|
6
|
+
|
|
1
7
|
# Web Feature Flags installation - Docs
|
|
2
8
|
|
|
3
9
|
1. 1
|
|
@@ -18,7 +24,7 @@
|
|
|
18
24
|
|
|
19
25
|
```html
|
|
20
26
|
<script>
|
|
21
|
-
!function(t,e){var o,n,p,r;e.__SV||(window.posthog && window.posthog.__loaded)||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagResult isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
27
|
+
!function(t,e){var o,n,p,r;e.__SV||(window.posthog && window.posthog.__loaded)||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}p||((p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",p.onerror=function(){p=null},(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r));var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagResult isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
22
28
|
posthog.init('<ph_project_token>', {
|
|
23
29
|
api_host: 'https://us.i.posthog.com',
|
|
24
30
|
defaults: '2026-05-30',
|
|
@@ -184,10 +190,6 @@
|
|
|
184
190
|
| [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
|
|
185
191
|
| [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
|
|
186
192
|
|
|
187
|
-
### Community questions
|
|
188
|
-
|
|
189
|
-
Ask a question
|
|
190
|
-
|
|
191
193
|
### Was this page useful?
|
|
192
194
|
|
|
193
195
|
HelpfulCould be better
|
|
@@ -65,7 +65,7 @@ STEP 9: Set up environment variables.
|
|
|
65
65
|
STEP 10: Verify and clean up.
|
|
66
66
|
- Check the project for errors. Look for type checking or build scripts in package.json.
|
|
67
67
|
- Ensure any components created were actually used.
|
|
68
|
-
- Run any linter or prettier-like scripts found in the package.json.
|
|
68
|
+
- Run any linter or prettier-like scripts found in the package.json, but ONLY on the files you have edited or created during this session. Never run formatting or linting across the entire project's codebase.
|
|
69
69
|
|
|
70
70
|
## Reference files
|
|
71
71
|
|
|
@@ -129,6 +129,7 @@ STEP 10: Verify and clean up.
|
|
|
129
129
|
- `references/flutter.md` - Flutter - docs
|
|
130
130
|
- `references/react-native.md` - React native - docs
|
|
131
131
|
- `references/identify-users.md` - Identify users - docs
|
|
132
|
+
- `references/COMMANDMENTS.md` - Framework-specific rules the integration must follow
|
|
132
133
|
|
|
133
134
|
Each framework reference contains SDK-specific installation, initialization, and usage patterns. Find the one matching the user's stack.
|
|
134
135
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Framework rules
|
|
2
|
+
|
|
3
|
+
Follow these when integrating PostHog into this framework.
|
|
4
|
+
|
|
5
|
+
- A missing PostHog configuration must never break the app — read keys optionally (never a required setting), guard init and capture behind their presence, and keep build and boot working with no PostHog environment set — but never silently: in development or debug builds fail loudly, using the language's idiomatic error, with the message "<VAR> variable required by PostHog is missing or un-configured, this causes events to be silently missed. This error stops appearing once <VAR> is configured" (substituting the actual variable name); production stays a no-op
|
|
@@ -24,14 +24,14 @@ This shows how to:
|
|
|
24
24
|
- Opt specific pages into SSR with `export const prerender = false`
|
|
25
25
|
- Keep most pages static for performance
|
|
26
26
|
- Track events from API routes using `posthog-node`
|
|
27
|
-
-
|
|
27
|
+
- Link client and server sessions automatically with the `tracing_headers` option
|
|
28
28
|
|
|
29
29
|
## Features
|
|
30
30
|
|
|
31
31
|
- **Hybrid rendering**: Static pages by default, SSR when needed
|
|
32
32
|
- **API routes**: Server-side endpoints for auth and event tracking
|
|
33
33
|
- **Dual tracking**: Events captured on both client and server
|
|
34
|
-
- **Session continuity**: Session ID
|
|
34
|
+
- **Session continuity**: Session and distinct ID forwarded automatically via `tracing_headers`
|
|
35
35
|
- **Product analytics**: Track login and burrito consideration events
|
|
36
36
|
- **Error tracking**: Manual error capture sent to PostHog
|
|
37
37
|
|
|
@@ -358,7 +358,10 @@ export default defineConfig({
|
|
|
358
358
|
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
359
359
|
posthog.init(apiKey || '', {
|
|
360
360
|
api_host: apiHost || 'https://us.i.posthog.com',
|
|
361
|
-
defaults: '2026-01-30'
|
|
361
|
+
defaults: '2026-01-30',
|
|
362
|
+
// Automatically add X-POSTHOG-SESSION-ID and X-POSTHOG-DISTINCT-ID headers
|
|
363
|
+
// to same-origin requests so server-side events join the same session.
|
|
364
|
+
tracing_headers: [window.location.hostname]
|
|
362
365
|
})
|
|
363
366
|
</script>
|
|
364
367
|
|
|
@@ -724,15 +727,13 @@ export const prerender = false;
|
|
|
724
727
|
source: 'client'
|
|
725
728
|
});
|
|
726
729
|
|
|
727
|
-
// Also send to server-side API for server tracking
|
|
730
|
+
// Also send to server-side API for server tracking. The session and distinct
|
|
731
|
+
// ID are added automatically by the tracing_headers option in posthog.init.
|
|
728
732
|
try {
|
|
729
|
-
const sessionId = window.posthog?.get_session_id?.() || null;
|
|
730
|
-
|
|
731
733
|
await fetch('/api/events/burrito', {
|
|
732
734
|
method: 'POST',
|
|
733
735
|
headers: {
|
|
734
|
-
'Content-Type': 'application/json'
|
|
735
|
-
'X-PostHog-Session-Id': sessionId || ''
|
|
736
|
+
'Content-Type': 'application/json'
|
|
736
737
|
},
|
|
737
738
|
body: JSON.stringify({
|
|
738
739
|
username: currentUser,
|
|
@@ -844,15 +845,12 @@ import PostHogLayout from '../layouts/PostHogLayout.astro';
|
|
|
844
845
|
}
|
|
845
846
|
|
|
846
847
|
try {
|
|
847
|
-
//
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
// Call the server-side login API
|
|
848
|
+
// Call the server-side login API. The session and distinct ID are added
|
|
849
|
+
// automatically by the tracing_headers option configured in posthog.init.
|
|
851
850
|
const response = await fetch('/api/auth/login', {
|
|
852
851
|
method: 'POST',
|
|
853
852
|
headers: {
|
|
854
|
-
'Content-Type': 'application/json'
|
|
855
|
-
'X-PostHog-Session-Id': sessionId || ''
|
|
853
|
+
'Content-Type': 'application/json'
|
|
856
854
|
},
|
|
857
855
|
body: JSON.stringify({ username, password })
|
|
858
856
|
});
|
|
@@ -20,7 +20,7 @@ This shows how to:
|
|
|
20
20
|
|
|
21
21
|
- Initialize PostHog on both client and server
|
|
22
22
|
- Track events from API routes using `posthog-node`
|
|
23
|
-
-
|
|
23
|
+
- Link client and server sessions automatically with the `tracing_headers` option
|
|
24
24
|
- Identify users on both client and server
|
|
25
25
|
- Capture errors via `posthog.captureException()`
|
|
26
26
|
- Reset PostHog state on logout
|
|
@@ -30,7 +30,7 @@ This shows how to:
|
|
|
30
30
|
- **Server-side rendering**: Full SSR with `output: 'server'`
|
|
31
31
|
- **API routes**: Server-side endpoints for auth and event tracking
|
|
32
32
|
- **Dual tracking**: Events captured on both client and server
|
|
33
|
-
- **Session continuity**: Session ID
|
|
33
|
+
- **Session continuity**: Session and distinct ID forwarded automatically via `tracing_headers`
|
|
34
34
|
- **Product analytics**: Track login and burrito consideration events
|
|
35
35
|
- **Session replay**: Enabled via PostHog snippet configuration
|
|
36
36
|
- **Error tracking**: Manual error capture sent to PostHog
|
|
@@ -148,18 +148,24 @@ export const POST: APIRoute = async ({ request }) => {
|
|
|
148
148
|
};
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
### Passing session
|
|
151
|
+
### Passing session context to the server (`src/components/posthog.astro`)
|
|
152
|
+
|
|
153
|
+
The `tracing_headers` option in `posthog.init` automatically adds the
|
|
154
|
+
`X-POSTHOG-SESSION-ID` and `X-POSTHOG-DISTINCT-ID` headers to same-origin
|
|
155
|
+
`fetch`/`XHR` requests, so the server route above receives them with no manual
|
|
156
|
+
wiring:
|
|
152
157
|
|
|
153
158
|
```javascript
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
posthog.init(apiKey, {
|
|
160
|
+
api_host: apiHost,
|
|
161
|
+
defaults: "2026-01-30",
|
|
162
|
+
tracing_headers: [window.location.hostname],
|
|
163
|
+
});
|
|
156
164
|
|
|
165
|
+
// Client fetches then need no PostHog headers of their own:
|
|
157
166
|
const response = await fetch("/api/auth/login", {
|
|
158
167
|
method: "POST",
|
|
159
|
-
headers: {
|
|
160
|
-
"Content-Type": "application/json",
|
|
161
|
-
"X-PostHog-Session-Id": sessionId || "",
|
|
162
|
-
},
|
|
168
|
+
headers: { "Content-Type": "application/json" },
|
|
163
169
|
body: JSON.stringify({ username, password }),
|
|
164
170
|
});
|
|
165
171
|
```
|
|
@@ -374,7 +380,10 @@ export default defineConfig({
|
|
|
374
380
|
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
375
381
|
posthog.init(apiKey || '', {
|
|
376
382
|
api_host: apiHost || 'https://us.i.posthog.com',
|
|
377
|
-
defaults: '2026-01-30'
|
|
383
|
+
defaults: '2026-01-30',
|
|
384
|
+
// Automatically add X-POSTHOG-SESSION-ID and X-POSTHOG-DISTINCT-ID headers
|
|
385
|
+
// to same-origin requests so server-side events join the same session.
|
|
386
|
+
tracing_headers: [window.location.hostname]
|
|
378
387
|
})
|
|
379
388
|
</script>
|
|
380
389
|
|
|
@@ -732,15 +741,13 @@ import PostHogLayout from '../layouts/PostHogLayout.astro';
|
|
|
732
741
|
source: 'client'
|
|
733
742
|
});
|
|
734
743
|
|
|
735
|
-
// Also send to server-side API for server tracking
|
|
744
|
+
// Also send to server-side API for server tracking. The session and distinct
|
|
745
|
+
// ID are added automatically by the tracing_headers option in posthog.init.
|
|
736
746
|
try {
|
|
737
|
-
const sessionId = window.posthog?.get_session_id?.() || null;
|
|
738
|
-
|
|
739
747
|
await fetch('/api/events/burrito', {
|
|
740
748
|
method: 'POST',
|
|
741
749
|
headers: {
|
|
742
|
-
'Content-Type': 'application/json'
|
|
743
|
-
'X-PostHog-Session-Id': sessionId || ''
|
|
750
|
+
'Content-Type': 'application/json'
|
|
744
751
|
},
|
|
745
752
|
body: JSON.stringify({
|
|
746
753
|
username: currentUser,
|
|
@@ -849,15 +856,12 @@ import PostHogLayout from '../layouts/PostHogLayout.astro';
|
|
|
849
856
|
}
|
|
850
857
|
|
|
851
858
|
try {
|
|
852
|
-
//
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
// Call the server-side login API
|
|
859
|
+
// Call the server-side login API. The session and distinct ID are added
|
|
860
|
+
// automatically by the tracing_headers option configured in posthog.init.
|
|
856
861
|
const response = await fetch('/api/auth/login', {
|
|
857
862
|
method: 'POST',
|
|
858
863
|
headers: {
|
|
859
|
-
'Content-Type': 'application/json'
|
|
860
|
-
'X-PostHog-Session-Id': sessionId || ''
|
|
864
|
+
'Content-Type': 'application/json'
|
|
861
865
|
},
|
|
862
866
|
body: JSON.stringify({ username, password })
|
|
863
867
|
});
|