@posthog/next 0.1.0 → 0.4.44

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.
Files changed (83) hide show
  1. package/dist/app/PostHogProvider.js +7 -7
  2. package/dist/app/PostHogProvider.js.map +1 -1
  3. package/dist/client/ClientPostHogProvider.js +2 -2
  4. package/dist/client/ClientPostHogProvider.js.map +1 -1
  5. package/dist/client/PostHogPageView.js +2 -2
  6. package/dist/client/PostHogPageView.js.map +1 -1
  7. package/dist/client/hooks.d.ts +1 -1
  8. package/dist/client/hooks.d.ts.map +1 -1
  9. package/dist/client/hooks.js +1 -1
  10. package/dist/client/hooks.js.map +1 -1
  11. package/dist/index.client.d.ts +5 -5
  12. package/dist/index.client.d.ts.map +1 -1
  13. package/dist/index.client.js +3 -3
  14. package/dist/index.client.js.map +1 -1
  15. package/dist/index.d.ts +8 -8
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.edge.d.ts +6 -6
  18. package/dist/index.edge.d.ts.map +1 -1
  19. package/dist/index.edge.js +4 -4
  20. package/dist/index.edge.js.map +1 -1
  21. package/dist/index.js +6 -6
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.react-server.d.ts +4 -4
  24. package/dist/index.react-server.d.ts.map +1 -1
  25. package/dist/index.react-server.js +3 -3
  26. package/dist/index.react-server.js.map +1 -1
  27. package/dist/middleware/postHogMiddleware.d.ts +12 -5
  28. package/dist/middleware/postHogMiddleware.d.ts.map +1 -1
  29. package/dist/middleware/postHogMiddleware.js +8 -7
  30. package/dist/middleware/postHogMiddleware.js.map +1 -1
  31. package/dist/pages/PostHogPageView.js +2 -2
  32. package/dist/pages/PostHogPageView.js.map +1 -1
  33. package/dist/pages/PostHogProvider.js +3 -3
  34. package/dist/pages/PostHogProvider.js.map +1 -1
  35. package/dist/pages/getServerSidePostHog.d.ts.map +1 -1
  36. package/dist/pages/getServerSidePostHog.js +8 -7
  37. package/dist/pages/getServerSidePostHog.js.map +1 -1
  38. package/dist/pages.client.d.ts +6 -0
  39. package/dist/pages.client.d.ts.map +1 -0
  40. package/dist/pages.client.js +8 -0
  41. package/dist/pages.client.js.map +1 -0
  42. package/dist/pages.d.ts +8 -8
  43. package/dist/pages.d.ts.map +1 -1
  44. package/dist/pages.edge.d.ts +7 -0
  45. package/dist/pages.edge.d.ts.map +1 -0
  46. package/dist/pages.edge.js +9 -0
  47. package/dist/pages.edge.js.map +1 -0
  48. package/dist/pages.js +6 -6
  49. package/dist/pages.js.map +1 -1
  50. package/dist/server/getPostHog.d.ts +1 -1
  51. package/dist/server/getPostHog.d.ts.map +1 -1
  52. package/dist/server/getPostHog.js +11 -9
  53. package/dist/server/getPostHog.js.map +1 -1
  54. package/dist/shared/config.d.ts +3 -0
  55. package/dist/shared/config.d.ts.map +1 -1
  56. package/dist/shared/config.js +12 -1
  57. package/dist/shared/config.js.map +1 -1
  58. package/dist/shared/cookie.js +1 -1
  59. package/dist/shared/cookie.js.map +1 -1
  60. package/dist/shared/tracing-headers.d.ts +38 -0
  61. package/dist/shared/tracing-headers.d.ts.map +1 -0
  62. package/dist/shared/tracing-headers.js +52 -0
  63. package/dist/shared/tracing-headers.js.map +1 -0
  64. package/package.json +13 -6
  65. package/src/app/PostHogProvider.tsx +8 -8
  66. package/src/client/ClientPostHogProvider.tsx +2 -2
  67. package/src/client/PostHogPageView.tsx +2 -2
  68. package/src/client/hooks.ts +1 -1
  69. package/src/index.client.ts +5 -5
  70. package/src/index.edge.ts +6 -6
  71. package/src/index.react-server.ts +4 -4
  72. package/src/index.ts +8 -8
  73. package/src/middleware/postHogMiddleware.ts +19 -11
  74. package/src/pages/PostHogPageView.tsx +2 -2
  75. package/src/pages/PostHogProvider.tsx +3 -3
  76. package/src/pages/getServerSidePostHog.ts +8 -7
  77. package/src/pages.client.ts +9 -0
  78. package/src/pages.edge.ts +10 -0
  79. package/src/pages.ts +8 -8
  80. package/src/server/getPostHog.ts +11 -9
  81. package/src/shared/config.ts +15 -1
  82. package/src/shared/cookie.ts +1 -1
  83. package/src/shared/tracing-headers.ts +67 -0
@@ -1,9 +1,10 @@
1
1
  import 'server-only';
2
2
  import { isFunction } from '@posthog/core';
3
- import { cookies } from 'next/headers';
4
- import { getOrCreateNodeClient } from './nodeClientCache';
5
- import { readPostHogCookie, cookieStateToProperties, isOptedOut } from '../shared/cookie';
6
- import { resolveApiKey } from '../shared/config';
3
+ import { cookies, headers } from 'next/headers.js';
4
+ import { getOrCreateNodeClient } from './nodeClientCache.js';
5
+ import { readPostHogCookie, isOptedOut } from '../shared/cookie.js';
6
+ import { resolveApiKey, resolveHostOrDefault } from '../shared/config.js';
7
+ import { readTracingHeaders, buildContextData } from '../shared/tracing-headers.js';
7
8
  /**
8
9
  * Returns a PostHog server client scoped to the current request.
9
10
  *
@@ -11,7 +12,7 @@ import { resolveApiKey } from '../shared/config';
11
12
  * request-scoped client. Methods like `getAllFlags()`, `getFeatureFlagResult()`,
12
13
  * and `capture()` automatically use the current user's identity.
13
14
  *
14
- * Calls `cookies()` internally, which opts the route into dynamic rendering.
15
+ * Calls `cookies()` and `headers()` internally, which opts the route into dynamic rendering.
15
16
  *
16
17
  * @param apiKey - PostHog project API key. If omitted, reads from `NEXT_PUBLIC_POSTHOG_KEY`.
17
18
  * @param options - Optional `posthog-node` configuration (e.g., `{ host: '...' }`).
@@ -31,16 +32,17 @@ import { resolveApiKey } from '../shared/config';
31
32
  */
32
33
  export async function getPostHog(apiKey, options) {
33
34
  const resolvedApiKey = resolveApiKey(apiKey);
34
- const host = options?.host ?? process.env.NEXT_PUBLIC_POSTHOG_HOST;
35
- const resolvedOptions = host ? { ...options, host } : options;
35
+ const host = resolveHostOrDefault(options?.host);
36
+ const resolvedOptions = { ...options, host };
36
37
  const client = await getOrCreateNodeClient(resolvedApiKey, resolvedOptions);
37
38
  const cookieStore = await cookies();
38
39
  if (isOptedOut(cookieStore, resolvedApiKey)) {
39
40
  return client;
40
41
  }
41
42
  const state = readPostHogCookie(cookieStore, resolvedApiKey);
42
- const properties = cookieStateToProperties(state);
43
- const contextData = { distinctId: state?.distinctId, sessionId: state?.sessionId, properties };
43
+ const headerStore = await headers();
44
+ const tracing = readTracingHeaders(headerStore);
45
+ const contextData = buildContextData(tracing, state);
44
46
  // Wrap the shared client in a Proxy that applies request-scoped context
45
47
  // to every method call. We can't use enterContext() here because
46
48
  // AsyncLocalStorage.enterWith() doesn't propagate back to the caller
@@ -1 +1 @@
1
- {"version":3,"file":"getPostHog.js","sourceRoot":"","sources":["../../src/server/getPostHog.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAe,EAAE,OAAiC,EAAqB;IACpG,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAA;IAClE,MAAM,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;IAC7D,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,cAAc,EAAE,eAAe,CAAC,CAAA;IAC3E,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAA;IAEnC,IAAI,UAAU,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAA;IACjB,CAAC;IAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IAC5D,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAA;IACjD,MAAM,WAAW,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,CAAA;IAE9F,wEAAwE;IACxE,iEAAiE;IACjE,qEAAqE;IACrE,oDAAoD;IACpD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACrB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;gBACzB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;YAC9C,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;YACjD,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpB,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;YACnG,CAAC;YACD,OAAO,KAAK,CAAA;QAAA,CACf;KACJ,CAAa,CAAA;AAAA,CACjB"}
1
+ {"version":3,"file":"getPostHog.js","sourceRoot":"","sources":["../../src/server/getPostHog.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAe,EAAE,OAAiC,EAAqB;IACpG,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAChD,MAAM,eAAe,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,cAAc,EAAE,eAAe,CAAC,CAAA;IAC3E,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAA;IAEnC,IAAI,UAAU,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAA;IACjB,CAAC;IAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IAC5D,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAA;IACnC,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;IAC/C,MAAM,WAAW,GAAG,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAEpD,wEAAwE;IACxE,iEAAiE;IACjE,qEAAqE;IACrE,oDAAoD;IACpD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACrB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;gBACzB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;YAC9C,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;YACjD,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpB,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;YACnG,CAAC;YACD,OAAO,KAAK,CAAA;QAAA,CACf;KACJ,CAAa,CAAA;AAAA,CACjB"}
@@ -16,7 +16,10 @@ export type PostHogServerConfig = PostHogOptions;
16
16
  *
17
17
  * Throws if neither is available.
18
18
  */
19
+ export declare function normalizeConfigValue(value?: unknown): string | undefined;
19
20
  export declare function resolveApiKey(apiKey?: string): string;
21
+ export declare function resolveHost(host?: string): string | undefined;
22
+ export declare function resolveHostOrDefault(host?: string): string;
20
23
  /**
21
24
  * Next.js-specific defaults for the posthog-js client.
22
25
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/shared/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;AAExD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAA;AAEhD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,EAAE,OAAO,CAAC,aAAa,CAKzD,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/shared/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAGlD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;AAExD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAA;AAEhD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGxE;AAED,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE7D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,EAAE,OAAO,CAAC,aAAa,CAKzD,CAAA"}
@@ -1,16 +1,27 @@
1
+ import { DEFAULT_API_HOST } from './constants.js';
1
2
  /**
2
3
  * Resolves the PostHog API key from an explicit value or the
3
4
  * `NEXT_PUBLIC_POSTHOG_KEY` environment variable.
4
5
  *
5
6
  * Throws if neither is available.
6
7
  */
8
+ export function normalizeConfigValue(value) {
9
+ const normalizedValue = typeof value === 'string' ? value.trim() : '';
10
+ return normalizedValue || undefined;
11
+ }
7
12
  export function resolveApiKey(apiKey) {
8
- const resolved = apiKey || process.env.NEXT_PUBLIC_POSTHOG_KEY;
13
+ const resolved = normalizeConfigValue(apiKey) ?? normalizeConfigValue(process.env.NEXT_PUBLIC_POSTHOG_KEY);
9
14
  if (!resolved) {
10
15
  throw new Error('[PostHog Next.js] apiKey is required. Either pass it explicitly or set the NEXT_PUBLIC_POSTHOG_KEY environment variable.');
11
16
  }
12
17
  return resolved;
13
18
  }
19
+ export function resolveHost(host) {
20
+ return normalizeConfigValue(host) ?? normalizeConfigValue(process.env.NEXT_PUBLIC_POSTHOG_HOST);
21
+ }
22
+ export function resolveHostOrDefault(host) {
23
+ return resolveHost(host) ?? DEFAULT_API_HOST;
24
+ }
14
25
  /**
15
26
  * Next.js-specific defaults for the posthog-js client.
16
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/shared/config.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe,EAAU;IACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAA;IAC9D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACX,0HAA0H,CAC7H,CAAA;IACL,CAAC;IACD,OAAO,QAAQ,CAAA;AAAA,CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA2B;IAC1D,gBAAgB,EAAE,KAAK;IACvB,WAAW,EAAE,qBAAqB;IAClC,kCAAkC,EAAE,QAAQ;IAC5C,8BAA8B,EAAE,IAAI;CACvC,CAAA"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/shared/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAcjD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAe,EAAsB;IACtE,MAAM,eAAe,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACrE,OAAO,eAAe,IAAI,SAAS,CAAA;AAAA,CACtC;AAED,MAAM,UAAU,aAAa,CAAC,MAAe,EAAU;IACnD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,IAAI,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;IAC1G,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACX,0HAA0H,CAC7H,CAAA;IACL,CAAC;IACD,OAAO,QAAQ,CAAA;AAAA,CAClB;AAED,MAAM,UAAU,WAAW,CAAC,IAAa,EAAsB;IAC3D,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;AAAA,CAClG;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAa,EAAU;IACxD,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAA;AAAA,CAC/C;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA2B;IAC1D,gBAAgB,EAAE,KAAK;IACvB,WAAW,EAAE,qBAAqB;IAClC,kCAAkC,EAAE,QAAQ;IAC5C,8BAA8B,EAAE,IAAI;CACvC,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { uuidv7, isNoLike, isArray } from '@posthog/core';
2
- import { COOKIE_PREFIX, COOKIE_SUFFIX } from './constants';
2
+ import { COOKIE_PREFIX, COOKIE_SUFFIX } from './constants.js';
3
3
  /**
4
4
  * Adapts a raw `Cookie` header string into a {@link CookieStore}.
5
5
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cookie.js","sourceRoot":"","sources":["../../src/shared/cookie.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cookie.js","sourceRoot":"","sources":["../../src/shared/cookie.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAU7D;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,YAAoB,EAAe;IACrE,MAAM,OAAO,GAA2B,EAAE,CAAA;IAC1C,IAAI,YAAY,EAAE,CAAC;QACf,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACnD,IAAI,GAAG,EAAE,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;YACzE,CAAC;QACL,CAAC;IACL,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAA;AAAA,CAC7F;AASD;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAU;IACzD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACtF,OAAO,GAAG,aAAa,GAAG,SAAS,GAAG,aAAa,EAAE,CAAA;AAAA,CACxD;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB,EAAU;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,MAAM,SAAS,GAAG,MAAM,EAAE,CAAA;IAC1B,OAAO,IAAI,CAAC,SAAS,CAAC;QAClB,WAAW,EAAE,WAAW;QACxB,UAAU,EAAE,WAAW;QACvB,WAAW,EAAE,WAAW;QACxB,MAAM,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC;KAChC,CAAC,CAAA;AAAA,CACL;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAoB,EAAE,MAAc,EAA6B;IAC/F,MAAM,UAAU,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACtC,OAAO,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAAA,CAC1D;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAgC,EAAsC;IAC1G,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO,SAAS,CAAA;IACpB,CAAC;IACD,MAAM,KAAK,GAA2B,EAAE,CAAA;IACxC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QAClB,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,SAAS,CAAA;IACvC,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAA;IACrC,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AAAA,CAC3D;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB,EAA6B;IAC/E,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,OAAO,IAAI,CAAA;IACf,CAAC;IAED,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACtC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAA;QACf,CAAC;QAED,gFAAgF;QAChF,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAEnE,OAAO;YACH,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;YACtC,YAAY,EAAE,MAAM,CAAC,WAAW,KAAK,YAAY;YACjD,SAAS,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YACxD,QAAQ,EAAE,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;SAClF,CAAA;IACL,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAA;IACf,CAAC;AAAA,CACJ;AAOD,MAAM,cAAc,GAAG,kBAAkB,CAAA;AAEzC,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,MAA4B,EAAU;IACvF,IAAI,MAAM,EAAE,wBAAwB,EAAE,CAAC;QACnC,OAAO,MAAM,CAAC,wBAAwB,CAAA;IAC1C,CAAC;IACD,IAAI,MAAM,EAAE,+BAA+B,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAC,+BAA+B,GAAG,MAAM,CAAA;IAC1D,CAAC;IACD,OAAO,cAAc,GAAG,MAAM,CAAA;AAAA,CACjC;AAMD,MAAM,UAAU,UAAU,CAAC,OAAoB,EAAE,MAAc,EAAE,MAAsB,EAAW;IAC9F,MAAM,UAAU,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAEtC,IAAI,MAAM,EAAE,CAAC;QACT,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACjC,CAAC;IAED,sDAAoD;IACpD,OAAO,MAAM,EAAE,4BAA4B,IAAI,KAAK,CAAA;AAAA,CACvD"}
@@ -0,0 +1,38 @@
1
+ import type { PostHogCookieState } from './cookie.js';
2
+ /**
3
+ * Header names used by the PostHog browser SDK's tracing headers feature.
4
+ *
5
+ * When `__add_tracing_headers` is enabled in the browser SDK, these headers
6
+ * are added to outgoing fetch/XHR requests so that server-side code can
7
+ * correlate events back to the browser session.
8
+ */
9
+ export declare const POSTHOG_SESSION_ID_HEADER = "x-posthog-session-id";
10
+ export declare const POSTHOG_DISTINCT_ID_HEADER = "x-posthog-distinct-id";
11
+ export declare const POSTHOG_WINDOW_ID_HEADER = "x-posthog-window-id";
12
+ export interface TracingHeaderValues {
13
+ distinctId?: string;
14
+ sessionId?: string;
15
+ windowId?: string;
16
+ }
17
+ /**
18
+ * Extracts PostHog tracing header values from request headers.
19
+ *
20
+ * Accepts either a Headers-like object with a `.get()` method (e.g. from
21
+ * `next/headers`) or a plain record (e.g. `ctx.req.headers` in Pages Router).
22
+ */
23
+ export declare function readTracingHeaders(headers: {
24
+ get(name: string): string | null;
25
+ } | Record<string, string | string[] | undefined>): TracingHeaderValues;
26
+ /**
27
+ * Builds context data by merging cookie state with tracing headers.
28
+ *
29
+ * Tracing headers take precedence over cookie values for `distinctId` and
30
+ * `sessionId` because they represent the browser's current state and are
31
+ * set per-request by the browser SDK.
32
+ */
33
+ export declare function buildContextData(tracing: TracingHeaderValues, state: PostHogCookieState | null): {
34
+ distinctId: string | undefined;
35
+ sessionId: string | undefined;
36
+ properties: Record<string, string> | undefined;
37
+ };
38
+ //# sourceMappingURL=tracing-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-headers.d.ts","sourceRoot":"","sources":["../../src/shared/tracing-headers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAGrD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,yBAAyB,CAAA;AAC/D,eAAO,MAAM,0BAA0B,0BAA0B,CAAA;AACjE,eAAO,MAAM,wBAAwB,wBAAwB,CAAA;AAE7D,MAAM,WAAW,mBAAmB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE;IAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAC9F,mBAAmB,CAcrB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,mBAAmB,EAC5B,KAAK,EAAE,kBAAkB,GAAG,IAAI,GACjC;IAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAAE,CAWnH"}
@@ -0,0 +1,52 @@
1
+ import { isFunction, isArray } from '@posthog/core';
2
+ import { cookieStateToProperties } from './cookie.js';
3
+ /**
4
+ * Header names used by the PostHog browser SDK's tracing headers feature.
5
+ *
6
+ * When `__add_tracing_headers` is enabled in the browser SDK, these headers
7
+ * are added to outgoing fetch/XHR requests so that server-side code can
8
+ * correlate events back to the browser session.
9
+ */
10
+ export const POSTHOG_SESSION_ID_HEADER = 'x-posthog-session-id';
11
+ export const POSTHOG_DISTINCT_ID_HEADER = 'x-posthog-distinct-id';
12
+ export const POSTHOG_WINDOW_ID_HEADER = 'x-posthog-window-id';
13
+ /**
14
+ * Extracts PostHog tracing header values from request headers.
15
+ *
16
+ * Accepts either a Headers-like object with a `.get()` method (e.g. from
17
+ * `next/headers`) or a plain record (e.g. `ctx.req.headers` in Pages Router).
18
+ */
19
+ export function readTracingHeaders(headers) {
20
+ const getValue = (name) => {
21
+ if (isFunction(headers.get)) {
22
+ return headers.get(name) ?? undefined;
23
+ }
24
+ const value = headers[name];
25
+ return typeof value === 'string' ? value : isArray(value) ? value[0] : undefined;
26
+ };
27
+ return {
28
+ distinctId: getValue(POSTHOG_DISTINCT_ID_HEADER) || undefined,
29
+ sessionId: getValue(POSTHOG_SESSION_ID_HEADER) || undefined,
30
+ windowId: getValue(POSTHOG_WINDOW_ID_HEADER) || undefined,
31
+ };
32
+ }
33
+ /**
34
+ * Builds context data by merging cookie state with tracing headers.
35
+ *
36
+ * Tracing headers take precedence over cookie values for `distinctId` and
37
+ * `sessionId` because they represent the browser's current state and are
38
+ * set per-request by the browser SDK.
39
+ */
40
+ export function buildContextData(tracing, state) {
41
+ const mergedProperties = {
42
+ ...cookieStateToProperties(state),
43
+ ...(tracing.sessionId ? { $session_id: tracing.sessionId } : {}),
44
+ ...(tracing.windowId ? { $window_id: tracing.windowId } : {}),
45
+ };
46
+ return {
47
+ distinctId: tracing.distinctId || state?.distinctId,
48
+ sessionId: tracing.sessionId || state?.sessionId,
49
+ properties: Object.keys(mergedProperties).length > 0 ? mergedProperties : undefined,
50
+ };
51
+ }
52
+ //# sourceMappingURL=tracing-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-headers.js","sourceRoot":"","sources":["../../src/shared/tracing-headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAA;AAC/D,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAA;AACjE,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAA;AAQ7D;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAC9B,OAA6F,EAC1E;IACnB,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAsB,EAAE,CAAC;QACnD,IAAI,UAAU,CAAE,OAA4B,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,OAAQ,OAAgD,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAA;QACnF,CAAC;QACD,MAAM,KAAK,GAAI,OAAyD,CAAC,IAAI,CAAC,CAAA;QAC9E,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAAA,CACnF,CAAA;IAED,OAAO;QACH,UAAU,EAAE,QAAQ,CAAC,0BAA0B,CAAC,IAAI,SAAS;QAC7D,SAAS,EAAE,QAAQ,CAAC,yBAAyB,CAAC,IAAI,SAAS;QAC3D,QAAQ,EAAE,QAAQ,CAAC,wBAAwB,CAAC,IAAI,SAAS;KAC5D,CAAA;AAAA,CACJ;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC5B,OAA4B,EAC5B,KAAgC,EACiF;IACjH,MAAM,gBAAgB,GAA2B;QAC7C,GAAG,uBAAuB,CAAC,KAAK,CAAC;QACjC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChE,CAAA;IACD,OAAO;QACH,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK,EAAE,UAAU;QACnD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,SAAS;QAChD,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;KACtF,CAAA;AAAA,CACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/next",
3
- "version": "0.1.0",
3
+ "version": "0.4.44",
4
4
  "description": "PostHog integration for Next.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "author": {
11
11
  "name": "PostHog",
12
- "email": "hey@posthog.com",
12
+ "email": "engineering@posthog.com",
13
13
  "url": "https://posthog.com"
14
14
  },
15
15
  "type": "module",
@@ -33,6 +33,11 @@
33
33
  },
34
34
  "./pages": {
35
35
  "types": "./dist/pages.d.ts",
36
+ "edge-light": "./dist/pages.edge.js",
37
+ "edge": "./dist/pages.edge.js",
38
+ "worker": "./dist/pages.edge.js",
39
+ "browser": "./dist/pages.client.js",
40
+ "react-server": "./dist/pages.js",
36
41
  "default": "./dist/pages.js"
37
42
  }
38
43
  },
@@ -45,9 +50,10 @@
45
50
  ],
46
51
  "dependencies": {
47
52
  "server-only": "^0.0.1",
48
- "@posthog/core": "1.23.2",
49
- "posthog-js": "1.359.1",
50
- "posthog-node": "5.28.0"
53
+ "@posthog/core": "1.28.4",
54
+ "@posthog/react": "1.9.0",
55
+ "posthog-js": "1.372.10",
56
+ "posthog-node": "5.33.4"
51
57
  },
52
58
  "devDependencies": {
53
59
  "@testing-library/jest-dom": "^6.6.3",
@@ -78,8 +84,9 @@
78
84
  },
79
85
  "scripts": {
80
86
  "clean": "rimraf dist",
81
- "build": "tsgo -p tsconfig.build.json",
87
+ "build": "tsgo -p tsconfig.build.json && pnpm check:esm-specifiers",
82
88
  "dev": "tsgo -p tsconfig.build.json --watch",
89
+ "check:esm-specifiers": "node ./scripts/check-relative-esm-specifiers.mjs",
83
90
  "test:unit": "jest",
84
91
  "test": "pnpm test:unit",
85
92
  "lint": "eslint src",
@@ -1,12 +1,12 @@
1
1
  import React from 'react'
2
2
  import type { PostHogConfig } from 'posthog-js'
3
- import { ClientPostHogProvider } from '../client/ClientPostHogProvider'
4
- import type { BootstrapConfig } from '../client/ClientPostHogProvider'
5
- import { cookies } from 'next/headers'
3
+ import { ClientPostHogProvider } from '../client/ClientPostHogProvider.js'
4
+ import type { BootstrapConfig } from '../client/ClientPostHogProvider.js'
5
+ import { cookies } from 'next/headers.js'
6
6
  import type { PostHogOptions } from 'posthog-node'
7
- import { getOrCreateNodeClient } from '../server/nodeClientCache'
8
- import { NEXTJS_CLIENT_DEFAULTS, resolveApiKey } from '../shared/config'
9
- import { readPostHogCookie, isOptedOut } from '../shared/cookie'
7
+ import { getOrCreateNodeClient } from '../server/nodeClientCache.js'
8
+ import { NEXTJS_CLIENT_DEFAULTS, resolveApiKey, resolveHostOrDefault } from '../shared/config.js'
9
+ import { readPostHogCookie, isOptedOut } from '../shared/cookie.js'
10
10
 
11
11
  type AllFlagsOptions = {
12
12
  groups?: Record<string, string>
@@ -82,7 +82,7 @@ export async function PostHogProvider({
82
82
  )
83
83
  }
84
84
 
85
- const host = clientOptions?.api_host ?? process.env.NEXT_PUBLIC_POSTHOG_HOST
85
+ const host = resolveHostOrDefault(clientOptions?.api_host)
86
86
  const resolvedOptions: Partial<PostHogConfig> = {
87
87
  ...NEXTJS_CLIENT_DEFAULTS,
88
88
  ...clientOptions,
@@ -131,7 +131,7 @@ async function evaluateFlags(
131
131
  return undefined
132
132
  }
133
133
 
134
- const host = serverOptions?.host ?? process.env.NEXT_PUBLIC_POSTHOG_HOST
134
+ const host = resolveHostOrDefault(serverOptions?.host)
135
135
  const nodeOptions: Partial<PostHogOptions> = { ...serverOptions, ...(host ? { host } : {}) }
136
136
  const client = await getOrCreateNodeClient(apiKey, nodeOptions)
137
137
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  import React from 'react'
4
4
  import posthogJs from 'posthog-js'
5
- import { PostHogProvider as ReactPostHogProvider } from 'posthog-js/react'
5
+ import { PostHogContext } from '@posthog/react'
6
6
  import type { BootstrapConfig, PostHogConfig } from 'posthog-js'
7
7
 
8
8
  export type { BootstrapConfig }
@@ -47,5 +47,5 @@ export function ClientPostHogProvider({ apiKey, options, bootstrap, children }:
47
47
  posthogJs.init(apiKey, mergedOptions)
48
48
  }
49
49
 
50
- return <ReactPostHogProvider client={posthogJs}>{children}</ReactPostHogProvider>
50
+ return <PostHogContext.Provider value={{ client: posthogJs, bootstrap }}>{children}</PostHogContext.Provider>
51
51
  }
@@ -1,8 +1,8 @@
1
1
  'use client'
2
2
 
3
3
  import { Suspense, useEffect } from 'react'
4
- import { usePathname, useSearchParams } from 'next/navigation'
5
- import { usePostHog } from 'posthog-js/react'
4
+ import { usePathname, useSearchParams } from 'next/navigation.js'
5
+ import { usePostHog } from '@posthog/react'
6
6
 
7
7
  /**
8
8
  * Tracks pageviews on route change in Next.js App Router.
@@ -5,4 +5,4 @@ export {
5
5
  useFeatureFlagResult as useFeatureFlag,
6
6
  useActiveFeatureFlags,
7
7
  PostHogFeature,
8
- } from 'posthog-js/react'
8
+ } from '@posthog/react'
@@ -1,9 +1,9 @@
1
1
  // Browser-safe exports. PostHogProvider (a server component) is excluded
2
2
  // because it imports posthog-node which uses Node.js APIs.
3
- export { PostHogPageView } from './client/PostHogPageView'
4
- export { DEFAULT_INGEST_PATH } from './shared/constants'
5
- export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks'
3
+ export { PostHogPageView } from './client/PostHogPageView.js'
4
+ export { DEFAULT_INGEST_PATH } from './shared/constants.js'
5
+ export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks.js'
6
6
 
7
7
  // Re-export types (type-only, erased at build time)
8
- export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider'
9
- export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware'
8
+ export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider.js'
9
+ export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware.js'
package/src/index.edge.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  // Edge-runtime exports (middleware). Excludes PostHogProvider and
2
2
  // posthog-node which require Node.js APIs.
3
- export { postHogMiddleware } from './middleware/postHogMiddleware'
4
- export { PostHogPageView } from './client/PostHogPageView'
5
- export { DEFAULT_INGEST_PATH } from './shared/constants'
6
- export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks'
3
+ export { postHogMiddleware } from './middleware/postHogMiddleware.js'
4
+ export { PostHogPageView } from './client/PostHogPageView.js'
5
+ export { DEFAULT_INGEST_PATH } from './shared/constants.js'
6
+ export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks.js'
7
7
 
8
8
  // Re-export types (type-only, erased at build time)
9
- export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider'
10
- export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware'
9
+ export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider.js'
10
+ export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware.js'
@@ -1,7 +1,7 @@
1
1
  // Server component exports (only available in react-server context)
2
- export { PostHogProvider } from './app/PostHogProvider'
3
- export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider'
2
+ export { PostHogProvider } from './app/PostHogProvider.js'
3
+ export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider.js'
4
4
 
5
5
  // Client-safe exports (re-exported so server components can also import them)
6
- export { PostHogPageView } from './client/PostHogPageView'
7
- export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks'
6
+ export { PostHogPageView } from './client/PostHogPageView.js'
7
+ export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks.js'
package/src/index.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { PostHogProvider } from './app/PostHogProvider'
2
- export { getPostHog } from './server/getPostHog'
3
- export { postHogMiddleware } from './middleware/postHogMiddleware'
4
- export { PostHogPageView } from './client/PostHogPageView'
5
- export { DEFAULT_INGEST_PATH } from './shared/constants'
6
- export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks'
7
- export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider'
8
- export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware'
1
+ export { PostHogProvider } from './app/PostHogProvider.js'
2
+ export { getPostHog } from './server/getPostHog.js'
3
+ export { postHogMiddleware } from './middleware/postHogMiddleware.js'
4
+ export { PostHogPageView } from './client/PostHogPageView.js'
5
+ export { DEFAULT_INGEST_PATH } from './shared/constants.js'
6
+ export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks.js'
7
+ export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider.js'
8
+ export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware.js'
@@ -1,11 +1,11 @@
1
1
  import 'server-only'
2
2
 
3
- import { NextResponse } from 'next/server'
4
- import type { NextRequest } from 'next/server'
5
- import { getPostHogCookieName, readPostHogCookie, serializePostHogCookie, isOptedOut } from '../shared/cookie'
6
- import { generateAnonymousId } from '../shared/identity'
7
- import { resolveApiKey } from '../shared/config'
8
- import { COOKIE_MAX_AGE_SECONDS, DEFAULT_API_HOST, DEFAULT_INGEST_PATH } from '../shared/constants'
3
+ import { NextResponse } from 'next/server.js'
4
+ import type { NextRequest } from 'next/server.js'
5
+ import { getPostHogCookieName, readPostHogCookie, serializePostHogCookie, isOptedOut } from '../shared/cookie.js'
6
+ import { generateAnonymousId } from '../shared/identity.js'
7
+ import { resolveApiKey, resolveHostOrDefault } from '../shared/config.js'
8
+ import { COOKIE_MAX_AGE_SECONDS, DEFAULT_INGEST_PATH } from '../shared/constants.js'
9
9
 
10
10
  export interface PostHogProxyOptions {
11
11
  /** Path prefix to intercept. Default: '/ingest'. */
@@ -43,10 +43,17 @@ export interface PostHogMiddlewareOptions {
43
43
  */
44
44
  response?: NextResponse
45
45
  /**
46
- * When true, skips cookie seeding when no consent cookie is present.
47
- * Mirrors the client-side `opt_out_capturing_by_default` option.
46
+ * Whether the middleware seeds the anonymous identity cookie on first visit.
47
+ *
48
+ * When `true` (the default), the middleware generates a UUIDv7 anonymous ID
49
+ * and sets the `ph_<key>_posthog` cookie on the first request so that server
50
+ * and client share the same identity from the first render.
51
+ *
52
+ * Set to `false` if you need user consent before setting any cookies. The
53
+ * middleware will not set the cookie and it will only be created by the
54
+ * client SDK.
48
55
  */
49
- optOutByDefault?: boolean
56
+ seedAnonymousCookie?: boolean
50
57
  /**
51
58
  * Custom name for the consent cookie.
52
59
  * Mirrors the client-side `consent_persistence_name` option.
@@ -87,7 +94,7 @@ function resolveProxyConfig(proxy: boolean | PostHogProxyOptions | undefined): R
87
94
  const prefix = options.pathPrefix ?? DEFAULT_INGEST_PATH
88
95
  return {
89
96
  pathPrefix: prefix.startsWith('/') ? prefix : `/${prefix}`,
90
- host: options.host ?? DEFAULT_API_HOST,
97
+ host: resolveHostOrDefault(options.host),
91
98
  }
92
99
  }
93
100
 
@@ -139,8 +146,9 @@ export function postHogMiddleware(config: PostHogMiddlewareOptions = {}) {
139
146
  const state = readPostHogCookie(request.cookies, apiKey)
140
147
  const response = config.response ?? NextResponse.next()
141
148
 
149
+ const shouldSeed = config.seedAnonymousCookie ?? true
142
150
  const optedOut = isOptedOut(request.cookies, apiKey, {
143
- opt_out_capturing_by_default: config.optOutByDefault,
151
+ opt_out_capturing_by_default: !shouldSeed,
144
152
  consent_persistence_name: config.consentCookieName,
145
153
  opt_out_capturing_cookie_prefix: config.consentCookiePrefix,
146
154
  })
@@ -1,6 +1,6 @@
1
1
  import { useEffect } from 'react'
2
- import { useRouter } from 'next/router'
3
- import { usePostHog } from 'posthog-js/react'
2
+ import { useRouter } from 'next/router.js'
3
+ import { usePostHog } from '@posthog/react'
4
4
 
5
5
  /**
6
6
  * Tracks pageviews on route change in Next.js Pages Router.
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
  import type { PostHogConfig, BootstrapConfig } from 'posthog-js'
3
- import { ClientPostHogProvider } from '../client/ClientPostHogProvider'
4
- import { NEXTJS_CLIENT_DEFAULTS, resolveApiKey } from '../shared/config'
3
+ import { ClientPostHogProvider } from '../client/ClientPostHogProvider.js'
4
+ import { NEXTJS_CLIENT_DEFAULTS, resolveApiKey, resolveHostOrDefault } from '../shared/config.js'
5
5
 
6
6
  export interface PagesPostHogProviderProps {
7
7
  /**
@@ -46,7 +46,7 @@ export function PostHogProvider({ apiKey: apiKeyProp, clientOptions, bootstrap,
46
46
  )
47
47
  }
48
48
 
49
- const host = clientOptions?.api_host ?? process.env.NEXT_PUBLIC_POSTHOG_HOST
49
+ const host = resolveHostOrDefault(clientOptions?.api_host)
50
50
  const resolvedOptions: Partial<PostHogConfig> = {
51
51
  ...NEXTJS_CLIENT_DEFAULTS,
52
52
  ...clientOptions,
@@ -1,8 +1,9 @@
1
1
  import type { GetServerSidePropsContext } from 'next'
2
2
  import type { PostHogOptions, IPostHog } from 'posthog-node'
3
- import { getOrCreateNodeClient } from '../server/nodeClientCache'
4
- import { cookieStoreFromHeader, readPostHogCookie, cookieStateToProperties, isOptedOut } from '../shared/cookie'
5
- import { resolveApiKey } from '../shared/config'
3
+ import { getOrCreateNodeClient } from '../server/nodeClientCache.js'
4
+ import { cookieStoreFromHeader, readPostHogCookie, isOptedOut } from '../shared/cookie.js'
5
+ import { resolveApiKey, resolveHostOrDefault } from '../shared/config.js'
6
+ import { readTracingHeaders, buildContextData } from '../shared/tracing-headers.js'
6
7
 
7
8
  /**
8
9
  * Creates a PostHog server client scoped to the current request.
@@ -33,16 +34,16 @@ export async function getServerSidePostHog(
33
34
  options?: Partial<PostHogOptions>
34
35
  ): Promise<IPostHog> {
35
36
  const resolvedApiKey = resolveApiKey(apiKey)
36
- const host = options?.host ?? process.env.NEXT_PUBLIC_POSTHOG_HOST
37
- const resolvedOptions = host ? { ...options, host } : options
37
+ const host = resolveHostOrDefault(options?.host)
38
+ const resolvedOptions = { ...options, host }
38
39
  const client = await getOrCreateNodeClient(resolvedApiKey, resolvedOptions)
39
40
 
40
41
  const cookieStore = cookieStoreFromHeader(ctx.req.headers.cookie || '')
41
42
 
42
43
  if (!isOptedOut(cookieStore, resolvedApiKey)) {
43
44
  const state = readPostHogCookie(cookieStore, resolvedApiKey)
44
- const properties = cookieStateToProperties(state)
45
- client.enterContext({ distinctId: state?.distinctId, sessionId: state?.sessionId, properties })
45
+ const tracing = readTracingHeaders(ctx.req.headers)
46
+ client.enterContext(buildContextData(tracing, state))
46
47
  }
47
48
 
48
49
  return client
@@ -0,0 +1,9 @@
1
+ // Client-runtime barrel for the `./pages` subpath. Resolved by Next.js's
2
+ // `browser` exports condition. Excludes `getPostHog`, `getServerSidePostHog`,
3
+ // and `postHogMiddleware`, which import `server-only` or `posthog-node` and
4
+ // must not be reachable from a client bundle.
5
+ export { PostHogProvider } from './pages/PostHogProvider.js'
6
+ export { PostHogPageView } from './pages/PostHogPageView.js'
7
+ export { DEFAULT_INGEST_PATH } from './shared/constants.js'
8
+ export type { PagesPostHogProviderProps } from './pages/PostHogProvider.js'
9
+ export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware.js'
@@ -0,0 +1,10 @@
1
+ // Edge-runtime barrel for the `./pages` subpath. Resolved by Next.js's
2
+ // `edge-light`, `edge`, and `worker` exports conditions. Excludes
3
+ // `getPostHog` and `getServerSidePostHog` which require Node.js APIs
4
+ // (via `posthog-node`) that aren't available in the Edge runtime.
5
+ export { PostHogProvider } from './pages/PostHogProvider.js'
6
+ export { postHogMiddleware } from './middleware/postHogMiddleware.js'
7
+ export { PostHogPageView } from './pages/PostHogPageView.js'
8
+ export { DEFAULT_INGEST_PATH } from './shared/constants.js'
9
+ export type { PagesPostHogProviderProps } from './pages/PostHogProvider.js'
10
+ export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware.js'
package/src/pages.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { PostHogProvider } from './pages/PostHogProvider'
2
- export { getServerSidePostHog } from './pages/getServerSidePostHog'
3
- export { getPostHog } from './server/getPostHog'
4
- export { postHogMiddleware } from './middleware/postHogMiddleware'
5
- export { PostHogPageView } from './pages/PostHogPageView'
6
- export { DEFAULT_INGEST_PATH } from './shared/constants'
7
- export type { PagesPostHogProviderProps } from './pages/PostHogProvider'
8
- export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware'
1
+ export { PostHogProvider } from './pages/PostHogProvider.js'
2
+ export { getServerSidePostHog } from './pages/getServerSidePostHog.js'
3
+ export { getPostHog } from './server/getPostHog.js'
4
+ export { postHogMiddleware } from './middleware/postHogMiddleware.js'
5
+ export { PostHogPageView } from './pages/PostHogPageView.js'
6
+ export { DEFAULT_INGEST_PATH } from './shared/constants.js'
7
+ export type { PagesPostHogProviderProps } from './pages/PostHogProvider.js'
8
+ export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware.js'