@posthog/next 0.1.0
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/LICENSE +299 -0
- package/README.md +122 -0
- package/dist/app/PostHogProvider.d.ts +62 -0
- package/dist/app/PostHogProvider.d.ts.map +1 -0
- package/dist/app/PostHogProvider.js +67 -0
- package/dist/app/PostHogProvider.js.map +1 -0
- package/dist/client/ClientPostHogProvider.d.ts +28 -0
- package/dist/client/ClientPostHogProvider.d.ts.map +1 -0
- package/dist/client/ClientPostHogProvider.js +34 -0
- package/dist/client/ClientPostHogProvider.js.map +1 -0
- package/dist/client/PostHogPageView.d.ts +30 -0
- package/dist/client/PostHogPageView.d.ts.map +1 -0
- package/dist/client/PostHogPageView.js +54 -0
- package/dist/client/PostHogPageView.js.map +1 -0
- package/dist/client/hooks.d.ts +2 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +3 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/index.client.d.ts +6 -0
- package/dist/index.client.d.ts.map +1 -0
- package/dist/index.client.js +6 -0
- package/dist/index.client.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.edge.d.ts +7 -0
- package/dist/index.edge.d.ts.map +1 -0
- package/dist/index.edge.js +7 -0
- package/dist/index.edge.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/index.react-server.d.ts +5 -0
- package/dist/index.react-server.d.ts.map +1 -0
- package/dist/index.react-server.js +6 -0
- package/dist/index.react-server.js.map +1 -0
- package/dist/middleware/postHogMiddleware.d.ts +95 -0
- package/dist/middleware/postHogMiddleware.d.ts.map +1 -0
- package/dist/middleware/postHogMiddleware.js +88 -0
- package/dist/middleware/postHogMiddleware.js.map +1 -0
- package/dist/pages/PostHogPageView.d.ts +25 -0
- package/dist/pages/PostHogPageView.d.ts.map +1 -0
- package/dist/pages/PostHogPageView.js +38 -0
- package/dist/pages/PostHogPageView.js.map +1 -0
- package/dist/pages/PostHogProvider.d.ts +16 -0
- package/dist/pages/PostHogProvider.d.ts.map +1 -0
- package/dist/pages/PostHogProvider.js +38 -0
- package/dist/pages/PostHogProvider.js.map +1 -0
- package/dist/pages/getServerSidePostHog.d.ts +27 -0
- package/dist/pages/getServerSidePostHog.d.ts.map +1 -0
- package/dist/pages/getServerSidePostHog.js +40 -0
- package/dist/pages/getServerSidePostHog.js.map +1 -0
- package/dist/pages.d.ts +9 -0
- package/dist/pages.d.ts.map +1 -0
- package/dist/pages.js +7 -0
- package/dist/pages.js.map +1 -0
- package/dist/server/getPostHog.d.ts +29 -0
- package/dist/server/getPostHog.d.ts.map +1 -0
- package/dist/server/getPostHog.js +61 -0
- package/dist/server/getPostHog.js.map +1 -0
- package/dist/server/nodeClientCache.d.ts +14 -0
- package/dist/server/nodeClientCache.d.ts.map +1 -0
- package/dist/server/nodeClientCache.js +33 -0
- package/dist/server/nodeClientCache.js.map +1 -0
- package/dist/shared/config.d.ts +36 -0
- package/dist/shared/config.d.ts.map +1 -0
- package/dist/shared/config.js +35 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/constants.d.ts +6 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +6 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/cookie.d.ts +69 -0
- package/dist/shared/cookie.d.ts.map +1 -0
- package/dist/shared/cookie.js +126 -0
- package/dist/shared/cookie.js.map +1 -0
- package/dist/shared/identity.d.ts +6 -0
- package/dist/shared/identity.d.ts.map +1 -0
- package/dist/shared/identity.js +9 -0
- package/dist/shared/identity.js.map +1 -0
- package/package.json +89 -0
- package/src/app/PostHogProvider.tsx +141 -0
- package/src/client/ClientPostHogProvider.tsx +51 -0
- package/src/client/PostHogPageView.tsx +63 -0
- package/src/client/hooks.ts +8 -0
- package/src/index.client.ts +9 -0
- package/src/index.edge.ts +10 -0
- package/src/index.react-server.ts +7 -0
- package/src/index.ts +8 -0
- package/src/middleware/postHogMiddleware.ts +170 -0
- package/src/pages/PostHogPageView.tsx +41 -0
- package/src/pages/PostHogProvider.tsx +61 -0
- package/src/pages/getServerSidePostHog.ts +49 -0
- package/src/pages.ts +8 -0
- package/src/server/getPostHog.ts +66 -0
- package/src/server/nodeClientCache.ts +37 -0
- package/src/shared/config.ts +52 -0
- package/src/shared/constants.ts +5 -0
- package/src/shared/cookie.ts +162 -0
- package/src/shared/identity.ts +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostHogPageView.d.ts","sourceRoot":"","sources":["../../src/client/PostHogPageView.tsx"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,eAAe,4CAM9B"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Suspense, useEffect } from 'react';
|
|
4
|
+
import { usePathname, useSearchParams } from 'next/navigation';
|
|
5
|
+
import { usePostHog } from 'posthog-js/react';
|
|
6
|
+
/**
|
|
7
|
+
* Tracks pageviews on route change in Next.js App Router.
|
|
8
|
+
*
|
|
9
|
+
* Place this component inside your `PostHogProvider` (typically in `app/layout.tsx`).
|
|
10
|
+
* It will automatically capture a `$pageview` event whenever the route changes.
|
|
11
|
+
*
|
|
12
|
+
* Includes its own Suspense boundary (required by `useSearchParams()`), so you
|
|
13
|
+
* don't need to wrap it in one yourself.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* // app/layout.tsx
|
|
18
|
+
* import { PostHogProvider, PostHogPageView } from '@posthog/next'
|
|
19
|
+
*
|
|
20
|
+
* export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
21
|
+
* return (
|
|
22
|
+
* <html>
|
|
23
|
+
* <body>
|
|
24
|
+
* <PostHogProvider apiKey={process.env.NEXT_PUBLIC_POSTHOG_KEY!}>
|
|
25
|
+
* <PostHogPageView />
|
|
26
|
+
* {children}
|
|
27
|
+
* </PostHogProvider>
|
|
28
|
+
* </body>
|
|
29
|
+
* </html>
|
|
30
|
+
* )
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function PostHogPageView() {
|
|
35
|
+
return (_jsx(Suspense, { fallback: null, children: _jsx(PageViewTracker, {}) }));
|
|
36
|
+
}
|
|
37
|
+
function PageViewTracker() {
|
|
38
|
+
const pathname = usePathname();
|
|
39
|
+
const searchParams = useSearchParams();
|
|
40
|
+
const posthog = usePostHog();
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!posthog) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
let url = pathname;
|
|
46
|
+
const search = searchParams.toString();
|
|
47
|
+
if (search) {
|
|
48
|
+
url = `${pathname}?${search}`;
|
|
49
|
+
}
|
|
50
|
+
posthog.capture('$pageview', { $current_url: url });
|
|
51
|
+
}, [pathname, searchParams, posthog]);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=PostHogPageView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostHogPageView.js","sourceRoot":"","sources":["../../src/client/PostHogPageView.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,eAAe,GAAG;IAC9B,OAAO,CACH,KAAC,QAAQ,IAAC,QAAQ,EAAE,IAAI,YACpB,KAAC,eAAe,KAAG,GACZ,CACd,CAAA;AAAA,CACJ;AAED,SAAS,eAAe,GAAG;IACvB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;IACtC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAE5B,SAAS,CAAC,GAAG,EAAE,CAAC;QACZ,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAM;QACV,CAAC;QAED,IAAI,GAAG,GAAG,QAAQ,CAAA;QAClB,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAA;QACtC,IAAI,MAAM,EAAE,CAAC;YACT,GAAG,GAAG,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAA;QACjC,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAA;IAAA,CACtD,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAAA;IAErC,OAAO,IAAI,CAAA;AAAA,CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,UAAU,EACV,oBAAoB,IAAI,cAAc,EACtC,qBAAqB,EACrB,cAAc,GACjB,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/client/hooks.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EACH,UAAU,EACV,oBAAoB,IAAI,cAAc,EACtC,qBAAqB,EACrB,cAAc,GACjB,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { PostHogPageView } from './client/PostHogPageView';
|
|
2
|
+
export { DEFAULT_INGEST_PATH } from './shared/constants';
|
|
3
|
+
export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks';
|
|
4
|
+
export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider';
|
|
5
|
+
export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware';
|
|
6
|
+
//# sourceMappingURL=index.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAGlG,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACvF,YAAY,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Browser-safe exports. PostHogProvider (a server component) is excluded
|
|
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';
|
|
6
|
+
//# sourceMappingURL=index.client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.client.js","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,2DAA2D;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
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';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAClG,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACvF,YAAY,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { postHogMiddleware } from './middleware/postHogMiddleware';
|
|
2
|
+
export { PostHogPageView } from './client/PostHogPageView';
|
|
3
|
+
export { DEFAULT_INGEST_PATH } from './shared/constants';
|
|
4
|
+
export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks';
|
|
5
|
+
export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider';
|
|
6
|
+
export type { PostHogMiddlewareOptions, PostHogProxyOptions } from './middleware/postHogMiddleware';
|
|
7
|
+
//# sourceMappingURL=index.edge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.edge.d.ts","sourceRoot":"","sources":["../src/index.edge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAGlG,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACvF,YAAY,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Edge-runtime exports (middleware). Excludes PostHogProvider and
|
|
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';
|
|
7
|
+
//# sourceMappingURL=index.edge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.edge.js","sourceRoot":"","sources":["../src/index.edge.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,2CAA2C;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { PostHogProvider } from './app/PostHogProvider';
|
|
2
|
+
export type { PostHogProviderProps, BootstrapFlagsConfig } from './app/PostHogProvider';
|
|
3
|
+
export { PostHogPageView } from './client/PostHogPageView';
|
|
4
|
+
export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks';
|
|
5
|
+
//# sourceMappingURL=index.react-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.react-server.d.ts","sourceRoot":"","sources":["../src/index.react-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAGvF,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Server component exports (only available in react-server context)
|
|
2
|
+
export { PostHogProvider } from './app/PostHogProvider';
|
|
3
|
+
// Client-safe exports (re-exported so server components can also import them)
|
|
4
|
+
export { PostHogPageView } from './client/PostHogPageView';
|
|
5
|
+
export { usePostHog, useFeatureFlag, useActiveFeatureFlags, PostHogFeature } from './client/hooks';
|
|
6
|
+
//# sourceMappingURL=index.react-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.react-server.js","sourceRoot":"","sources":["../src/index.react-server.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGvD,8EAA8E;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import type { NextRequest } from 'next/server';
|
|
4
|
+
export interface PostHogProxyOptions {
|
|
5
|
+
/** Path prefix to intercept. Default: '/ingest'. */
|
|
6
|
+
pathPrefix?: string;
|
|
7
|
+
/** PostHog ingest host to rewrite to. Default: 'https://us.i.posthog.com' */
|
|
8
|
+
host?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for the PostHog middleware.
|
|
12
|
+
*/
|
|
13
|
+
export interface PostHogMiddlewareOptions {
|
|
14
|
+
/**
|
|
15
|
+
* PostHog project API key (starts with phc_).
|
|
16
|
+
* If omitted, reads from `NEXT_PUBLIC_POSTHOG_KEY` env var.
|
|
17
|
+
*/
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
/** Cookie max age in seconds. Default: 365 days. */
|
|
20
|
+
cookieMaxAgeSeconds?: number;
|
|
21
|
+
/**
|
|
22
|
+
* An existing response to seed the PostHog cookie on.
|
|
23
|
+
*
|
|
24
|
+
* When provided, the middleware seeds the identity cookie on this response
|
|
25
|
+
* instead of creating a new one via `NextResponse.next()`. This enables
|
|
26
|
+
* composition with other middleware.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* export default async function middleware(request: NextRequest) {
|
|
31
|
+
* const response = NextResponse.next()
|
|
32
|
+
* response.headers.set('x-custom', 'value')
|
|
33
|
+
* return postHogMiddleware({ response })(request)
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
response?: NextResponse;
|
|
38
|
+
/**
|
|
39
|
+
* When true, skips cookie seeding when no consent cookie is present.
|
|
40
|
+
* Mirrors the client-side `opt_out_capturing_by_default` option.
|
|
41
|
+
*/
|
|
42
|
+
optOutByDefault?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Custom name for the consent cookie.
|
|
45
|
+
* Mirrors the client-side `consent_persistence_name` option.
|
|
46
|
+
*/
|
|
47
|
+
consentCookieName?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Custom prefix for the consent cookie (appended with apiKey).
|
|
50
|
+
* Mirrors the client-side `opt_out_capturing_cookie_prefix` option.
|
|
51
|
+
*/
|
|
52
|
+
consentCookiePrefix?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Proxy PostHog API requests through your app's domain.
|
|
55
|
+
*
|
|
56
|
+
* When enabled, requests matching the path prefix (default: `/ingest`)
|
|
57
|
+
* are rewritten to the PostHog ingest host, allowing SDK traffic to
|
|
58
|
+
* flow through your app's domain.
|
|
59
|
+
*
|
|
60
|
+
* Set to `true` for defaults, or pass an object to customize the path
|
|
61
|
+
* prefix and/or target host.
|
|
62
|
+
*
|
|
63
|
+
* When using the proxy, set `api_host` to the path prefix (e.g. `/ingest`)
|
|
64
|
+
* in your PostHogProvider options so the client SDK sends requests to
|
|
65
|
+
* your app's domain.
|
|
66
|
+
*/
|
|
67
|
+
proxy?: boolean | PostHogProxyOptions;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Creates a Next.js middleware that seeds the PostHog identity cookie
|
|
71
|
+
* on first visit and optionally rewrites API requests to PostHog's
|
|
72
|
+
* ingest host.
|
|
73
|
+
*
|
|
74
|
+
* @example Standalone (simplest — reads apiKey from NEXT_PUBLIC_POSTHOG_KEY)
|
|
75
|
+
* ```ts
|
|
76
|
+
* // middleware.ts
|
|
77
|
+
* import { postHogMiddleware } from '@posthog/next'
|
|
78
|
+
*
|
|
79
|
+
* export default postHogMiddleware({ proxy: true })
|
|
80
|
+
*
|
|
81
|
+
* export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'] }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example Composed with other middleware
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { postHogMiddleware } from '@posthog/next'
|
|
87
|
+
*
|
|
88
|
+
* export default async function middleware(request: NextRequest) {
|
|
89
|
+
* const response = otherMiddleware(request)
|
|
90
|
+
* return postHogMiddleware({ proxy: true, response })(request)
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function postHogMiddleware(config?: PostHogMiddlewareOptions): (request: NextRequest) => Promise<NextResponse<unknown>>;
|
|
95
|
+
//# sourceMappingURL=postHogMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postHogMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/postHogMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAM9C,MAAM,WAAW,mBAAmB;IAChC,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAA;CACxC;AA2BD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,wBAA6B,4DA2CtE"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import { NextResponse } from 'next/server';
|
|
3
|
+
import { getPostHogCookieName, readPostHogCookie, serializePostHogCookie, isOptedOut } from '../shared/cookie';
|
|
4
|
+
import { generateAnonymousId } from '../shared/identity';
|
|
5
|
+
import { resolveApiKey } from '../shared/config';
|
|
6
|
+
import { COOKIE_MAX_AGE_SECONDS, DEFAULT_API_HOST, DEFAULT_INGEST_PATH } from '../shared/constants';
|
|
7
|
+
function resolveProxyConfig(proxy) {
|
|
8
|
+
if (!proxy) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const options = typeof proxy === 'object' ? proxy : {};
|
|
12
|
+
const prefix = options.pathPrefix ?? DEFAULT_INGEST_PATH;
|
|
13
|
+
return {
|
|
14
|
+
pathPrefix: prefix.startsWith('/') ? prefix : `/${prefix}`,
|
|
15
|
+
host: options.host ?? DEFAULT_API_HOST,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function rewriteToPostHog(request, config) {
|
|
19
|
+
const pathname = request.nextUrl.pathname.slice(config.pathPrefix.length) || '/';
|
|
20
|
+
// eslint-disable-next-line compat/compat
|
|
21
|
+
const url = new URL(pathname, config.host);
|
|
22
|
+
url.search = request.nextUrl.search;
|
|
23
|
+
return NextResponse.rewrite(url);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates a Next.js middleware that seeds the PostHog identity cookie
|
|
27
|
+
* on first visit and optionally rewrites API requests to PostHog's
|
|
28
|
+
* ingest host.
|
|
29
|
+
*
|
|
30
|
+
* @example Standalone (simplest — reads apiKey from NEXT_PUBLIC_POSTHOG_KEY)
|
|
31
|
+
* ```ts
|
|
32
|
+
* // middleware.ts
|
|
33
|
+
* import { postHogMiddleware } from '@posthog/next'
|
|
34
|
+
*
|
|
35
|
+
* export default postHogMiddleware({ proxy: true })
|
|
36
|
+
*
|
|
37
|
+
* export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'] }
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @example Composed with other middleware
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { postHogMiddleware } from '@posthog/next'
|
|
43
|
+
*
|
|
44
|
+
* export default async function middleware(request: NextRequest) {
|
|
45
|
+
* const response = otherMiddleware(request)
|
|
46
|
+
* return postHogMiddleware({ proxy: true, response })(request)
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export function postHogMiddleware(config = {}) {
|
|
51
|
+
const apiKey = resolveApiKey(config.apiKey);
|
|
52
|
+
const proxyConfig = resolveProxyConfig(config.proxy);
|
|
53
|
+
return async function middleware(request) {
|
|
54
|
+
// Proxy ingest requests to PostHog's host. These are API calls
|
|
55
|
+
// from the browser SDK and don't need cookie seeding.
|
|
56
|
+
if (proxyConfig && request.nextUrl.pathname.startsWith(proxyConfig.pathPrefix)) {
|
|
57
|
+
return rewriteToPostHog(request, proxyConfig);
|
|
58
|
+
}
|
|
59
|
+
const cookieName = getPostHogCookieName(apiKey);
|
|
60
|
+
const state = readPostHogCookie(request.cookies, apiKey);
|
|
61
|
+
const response = config.response ?? NextResponse.next();
|
|
62
|
+
const optedOut = isOptedOut(request.cookies, apiKey, {
|
|
63
|
+
opt_out_capturing_by_default: config.optOutByDefault,
|
|
64
|
+
consent_persistence_name: config.consentCookieName,
|
|
65
|
+
opt_out_capturing_cookie_prefix: config.consentCookiePrefix,
|
|
66
|
+
});
|
|
67
|
+
if (optedOut) {
|
|
68
|
+
if (state) {
|
|
69
|
+
response.cookies.delete(cookieName);
|
|
70
|
+
}
|
|
71
|
+
return response;
|
|
72
|
+
}
|
|
73
|
+
// Seed the PostHog cookie on first visit so server and client
|
|
74
|
+
// share the same identity from the first render.
|
|
75
|
+
if (!state) {
|
|
76
|
+
const distinctId = generateAnonymousId();
|
|
77
|
+
response.cookies.set(cookieName, serializePostHogCookie(distinctId), {
|
|
78
|
+
path: '/',
|
|
79
|
+
sameSite: 'lax',
|
|
80
|
+
secure: request.nextUrl.protocol === 'https:',
|
|
81
|
+
maxAge: config.cookieMaxAgeSeconds ?? COOKIE_MAX_AGE_SECONDS,
|
|
82
|
+
httpOnly: false,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return response;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=postHogMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postHogMiddleware.js","sourceRoot":"","sources":["../../src/middleware/postHogMiddleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks pageviews on route change in Next.js Pages Router.
|
|
3
|
+
*
|
|
4
|
+
* Place this component inside your `PostHogProvider` in `pages/_app.tsx`.
|
|
5
|
+
* It will automatically capture a `$pageview` event whenever the route changes.
|
|
6
|
+
*
|
|
7
|
+
* Uses `router.asPath` which includes query parameters and hash fragments.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* // pages/_app.tsx
|
|
12
|
+
* import { PostHogProvider, PostHogPageView } from '@posthog/next/pages'
|
|
13
|
+
*
|
|
14
|
+
* export default function App({ Component, pageProps }: AppProps) {
|
|
15
|
+
* return (
|
|
16
|
+
* <PostHogProvider apiKey={process.env.NEXT_PUBLIC_POSTHOG_KEY!}>
|
|
17
|
+
* <PostHogPageView />
|
|
18
|
+
* <Component {...pageProps} />
|
|
19
|
+
* </PostHogProvider>
|
|
20
|
+
* )
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function PostHogPageView(): null;
|
|
25
|
+
//# sourceMappingURL=PostHogPageView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostHogPageView.d.ts","sourceRoot":"","sources":["../../src/pages/PostHogPageView.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,SAa9B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useRouter } from 'next/router';
|
|
3
|
+
import { usePostHog } from 'posthog-js/react';
|
|
4
|
+
/**
|
|
5
|
+
* Tracks pageviews on route change in Next.js Pages Router.
|
|
6
|
+
*
|
|
7
|
+
* Place this component inside your `PostHogProvider` in `pages/_app.tsx`.
|
|
8
|
+
* It will automatically capture a `$pageview` event whenever the route changes.
|
|
9
|
+
*
|
|
10
|
+
* Uses `router.asPath` which includes query parameters and hash fragments.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* // pages/_app.tsx
|
|
15
|
+
* import { PostHogProvider, PostHogPageView } from '@posthog/next/pages'
|
|
16
|
+
*
|
|
17
|
+
* export default function App({ Component, pageProps }: AppProps) {
|
|
18
|
+
* return (
|
|
19
|
+
* <PostHogProvider apiKey={process.env.NEXT_PUBLIC_POSTHOG_KEY!}>
|
|
20
|
+
* <PostHogPageView />
|
|
21
|
+
* <Component {...pageProps} />
|
|
22
|
+
* </PostHogProvider>
|
|
23
|
+
* )
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function PostHogPageView() {
|
|
28
|
+
const router = useRouter();
|
|
29
|
+
const posthog = usePostHog();
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!posthog || !router.isReady) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
posthog.capture('$pageview', { $current_url: router.asPath });
|
|
35
|
+
}, [router.asPath, router.isReady, posthog]);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=PostHogPageView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostHogPageView.js","sourceRoot":"","sources":["../../src/pages/PostHogPageView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,eAAe,GAAG;IAC9B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAE5B,SAAS,CAAC,GAAG,EAAE,CAAC;QACZ,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAM;QACV,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;IAAA,CAChE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAE5C,OAAO,IAAI,CAAA;AAAA,CACd"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PostHogConfig, BootstrapConfig } from 'posthog-js';
|
|
3
|
+
export interface PagesPostHogProviderProps {
|
|
4
|
+
/**
|
|
5
|
+
* PostHog project API key (starts with phc_).
|
|
6
|
+
* If omitted, reads from `NEXT_PUBLIC_POSTHOG_KEY` env var.
|
|
7
|
+
*/
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
/** Optional posthog-js configuration overrides. */
|
|
10
|
+
clientOptions?: Partial<PostHogConfig>;
|
|
11
|
+
/** Server-evaluated bootstrap data from getServerSidePostHog. */
|
|
12
|
+
bootstrap?: BootstrapConfig;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export declare function PostHogProvider({ apiKey: apiKeyProp, clientOptions, bootstrap, children }: PagesPostHogProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=PostHogProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostHogProvider.d.ts","sourceRoot":"","sources":["../../src/pages/PostHogProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAIhE,MAAM,WAAW,yBAAyB;IACtC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IACtC,iEAAiE;IACjE,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC5B;AAsBD,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,yBAAyB,2CAsBpH"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ClientPostHogProvider } from '../client/ClientPostHogProvider';
|
|
3
|
+
import { NEXTJS_CLIENT_DEFAULTS, resolveApiKey } from '../shared/config';
|
|
4
|
+
/**
|
|
5
|
+
* PostHog provider for Next.js Pages Router.
|
|
6
|
+
*
|
|
7
|
+
* Place this in your `pages/_app.tsx` wrapping `<Component {...pageProps} />`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import { PostHogProvider } from '@posthog/next/pages'
|
|
12
|
+
*
|
|
13
|
+
* export default function App({ Component, pageProps }: AppProps) {
|
|
14
|
+
* return (
|
|
15
|
+
* <PostHogProvider apiKey={process.env.NEXT_PUBLIC_POSTHOG_KEY!}>
|
|
16
|
+
* <Component {...pageProps} />
|
|
17
|
+
* </PostHogProvider>
|
|
18
|
+
* )
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
let apiKeyWarned = false;
|
|
23
|
+
export function PostHogProvider({ apiKey: apiKeyProp, clientOptions, bootstrap, children }) {
|
|
24
|
+
const apiKey = resolveApiKey(apiKeyProp);
|
|
25
|
+
if (!apiKeyWarned && !apiKey.startsWith('phc_')) {
|
|
26
|
+
apiKeyWarned = true;
|
|
27
|
+
// eslint-disable-next-line no-console
|
|
28
|
+
console.warn(`[PostHog Next.js] apiKey "${apiKey}" does not start with "phc_". This may not be a valid PostHog project API key.`);
|
|
29
|
+
}
|
|
30
|
+
const host = clientOptions?.api_host ?? process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
|
31
|
+
const resolvedOptions = {
|
|
32
|
+
...NEXTJS_CLIENT_DEFAULTS,
|
|
33
|
+
...clientOptions,
|
|
34
|
+
...(host ? { api_host: host } : {}),
|
|
35
|
+
};
|
|
36
|
+
return (_jsx(ClientPostHogProvider, { apiKey: apiKey, options: resolvedOptions, bootstrap: bootstrap, children: children }));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=PostHogProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostHogProvider.js","sourceRoot":"","sources":["../../src/pages/PostHogProvider.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AACvE,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAexE;;;;;;;;;;;;;;;;;GAiBG;AACH,IAAI,YAAY,GAAG,KAAK,CAAA;AAExB,MAAM,UAAU,eAAe,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAA6B,EAAE;IACnH,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IACxC,IAAI,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,YAAY,GAAG,IAAI,CAAA;QACnB,sCAAsC;QACtC,OAAO,CAAC,IAAI,CACR,6BAA6B,MAAM,gFAAgF,CACtH,CAAA;IACL,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,EAAE,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAA;IAC5E,MAAM,eAAe,GAA2B;QAC5C,GAAG,sBAAsB;QACzB,GAAG,aAAa;QAChB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAA;IAED,OAAO,CACH,KAAC,qBAAqB,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,YAChF,QAAQ,GACW,CAC3B,CAAA;AAAA,CACJ"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { GetServerSidePropsContext } from 'next';
|
|
2
|
+
import type { PostHogOptions, IPostHog } from 'posthog-node';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a PostHog server client scoped to the current request.
|
|
5
|
+
*
|
|
6
|
+
* Reads the user's identity from the PostHog cookie in request headers
|
|
7
|
+
* and sets it as context via `enterContext()`. The returned client is
|
|
8
|
+
* ready to use — methods like `getAllFlags()`, `getFeatureFlagResult()`,
|
|
9
|
+
* and `capture()` automatically use the current user's identity.
|
|
10
|
+
*
|
|
11
|
+
* @param ctx - The Next.js GetServerSidePropsContext
|
|
12
|
+
* @param apiKey - PostHog project API key. If omitted, reads from NEXT_PUBLIC_POSTHOG_KEY.
|
|
13
|
+
* @param options - Optional posthog-node configuration
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* import { getServerSidePostHog } from '@posthog/next/pages'
|
|
18
|
+
*
|
|
19
|
+
* export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
|
20
|
+
* const posthog = await getServerSidePostHog(ctx)
|
|
21
|
+
* const flags = await posthog.getAllFlagsAndPayloads()
|
|
22
|
+
* return { props: { posthogBootstrap: flags } }
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function getServerSidePostHog(ctx: GetServerSidePropsContext, apiKey?: string, options?: Partial<PostHogOptions>): Promise<IPostHog>;
|
|
27
|
+
//# sourceMappingURL=getServerSidePostHog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getServerSidePostHog.d.ts","sourceRoot":"","sources":["../../src/pages/getServerSidePostHog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,MAAM,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAK5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,oBAAoB,CACtC,GAAG,EAAE,yBAAyB,EAC9B,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAClC,OAAO,CAAC,QAAQ,CAAC,CAenB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getOrCreateNodeClient } from '../server/nodeClientCache';
|
|
2
|
+
import { cookieStoreFromHeader, readPostHogCookie, cookieStateToProperties, isOptedOut } from '../shared/cookie';
|
|
3
|
+
import { resolveApiKey } from '../shared/config';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a PostHog server client scoped to the current request.
|
|
6
|
+
*
|
|
7
|
+
* Reads the user's identity from the PostHog cookie in request headers
|
|
8
|
+
* and sets it as context via `enterContext()`. The returned client is
|
|
9
|
+
* ready to use — methods like `getAllFlags()`, `getFeatureFlagResult()`,
|
|
10
|
+
* and `capture()` automatically use the current user's identity.
|
|
11
|
+
*
|
|
12
|
+
* @param ctx - The Next.js GetServerSidePropsContext
|
|
13
|
+
* @param apiKey - PostHog project API key. If omitted, reads from NEXT_PUBLIC_POSTHOG_KEY.
|
|
14
|
+
* @param options - Optional posthog-node configuration
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { getServerSidePostHog } from '@posthog/next/pages'
|
|
19
|
+
*
|
|
20
|
+
* export const getServerSideProps: GetServerSideProps = async (ctx) => {
|
|
21
|
+
* const posthog = await getServerSidePostHog(ctx)
|
|
22
|
+
* const flags = await posthog.getAllFlagsAndPayloads()
|
|
23
|
+
* return { props: { posthogBootstrap: flags } }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export async function getServerSidePostHog(ctx, apiKey, options) {
|
|
28
|
+
const resolvedApiKey = resolveApiKey(apiKey);
|
|
29
|
+
const host = options?.host ?? process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
|
30
|
+
const resolvedOptions = host ? { ...options, host } : options;
|
|
31
|
+
const client = await getOrCreateNodeClient(resolvedApiKey, resolvedOptions);
|
|
32
|
+
const cookieStore = cookieStoreFromHeader(ctx.req.headers.cookie || '');
|
|
33
|
+
if (!isOptedOut(cookieStore, resolvedApiKey)) {
|
|
34
|
+
const state = readPostHogCookie(cookieStore, resolvedApiKey);
|
|
35
|
+
const properties = cookieStateToProperties(state);
|
|
36
|
+
client.enterContext({ distinctId: state?.distinctId, sessionId: state?.sessionId, properties });
|
|
37
|
+
}
|
|
38
|
+
return client;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=getServerSidePostHog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getServerSidePostHog.js","sourceRoot":"","sources":["../../src/pages/getServerSidePostHog.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACtC,GAA8B,EAC9B,MAAe,EACf,OAAiC,EAChB;IACjB,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;IAE3E,MAAM,WAAW,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAA;IAEvE,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,iBAAiB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;QAC5D,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAA;QACjD,MAAM,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAA;IACnG,CAAC;IAED,OAAO,MAAM,CAAA;AAAA,CAChB"}
|
package/dist/pages.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
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';
|
|
9
|
+
//# sourceMappingURL=pages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../src/pages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,YAAY,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,YAAY,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA"}
|
package/dist/pages.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
//# sourceMappingURL=pages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.js","sourceRoot":"","sources":["../src/pages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA"}
|