Skip to content

Commit e128c74

Browse files
committed
docs: integrate PostHog analytics for enhanced tracking
1 parent 49899bc commit e128c74

File tree

14 files changed

+288
-18
lines changed

14 files changed

+288
-18
lines changed

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# funnel Documentation
22

3-
this is the documentation site for funnel, built with Next.js and fumadocs
3+
this is the documentation site for funnel, built with Next.js and fumadocs

docs/bun.lock

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"mermaid": "11.8.1",
1515
"next": "15.3.4",
1616
"ogl": "1.0.11",
17+
"posthog-js": "1.257.1",
18+
"posthog-node": "5.6.0",
1719
"react": "^19.1.0",
1820
"react-dom": "^19.1.0",
1921
"rehype-katex": "7.0.1",
@@ -629,6 +631,8 @@
629631

630632
"confbox": ["[email protected]", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="],
631633

634+
"core-js": ["[email protected]", "", {}, "sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw=="],
635+
632636
"cose-base": ["[email protected]", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="],
633637

634638
"cross-spawn": ["[email protected]", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
@@ -839,6 +843,8 @@
839843

840844
"fdir": ["[email protected]", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
841845

846+
"fflate": ["[email protected]", "", {}, "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="],
847+
842848
"file-entry-cache": ["[email protected]", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="],
843849

844850
"fill-range": ["[email protected]", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
@@ -1317,6 +1323,12 @@
13171323

13181324
"postcss-selector-parser": ["[email protected]", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
13191325

1326+
"posthog-js": ["[email protected]", "", { "dependencies": { "core-js": "^3.38.1", "fflate": "^0.4.8", "preact": "^10.19.3", "web-vitals": "^4.2.4" }, "peerDependencies": { "@rrweb/types": "2.0.0-alpha.17", "rrweb-snapshot": "2.0.0-alpha.17" }, "optionalPeers": ["@rrweb/types", "rrweb-snapshot"] }, "sha512-29kk3IO/LkPQ8E1cds6a2sWr5iN4BovgL+EMzRK9hQXbI6D3FJnQ7zLU6EUpktt6pHnqGpfO3BTEcflcDYkHBg=="],
1327+
1328+
"posthog-node": ["[email protected]", "", {}, "sha512-MVXxKmqAYp2cPBrN1YMhnhYsJYIu6yc6wumbHz1dbo67wZBf2WtMm67Uh+4VCrp07049qierWlxQqz1W5zGDeg=="],
1329+
1330+
"preact": ["[email protected]", "", {}, "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA=="],
1331+
13201332
"prelude-ls": ["[email protected]", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
13211333

13221334
"prop-types": ["[email protected]", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
@@ -1583,6 +1595,8 @@
15831595

15841596
"web-namespaces": ["[email protected]", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
15851597

1598+
"web-vitals": ["[email protected]", "", {}, "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="],
1599+
15861600
"which": ["[email protected]", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
15871601

15881602
"which-boxed-primitive": ["[email protected]", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="],

docs/instrumentation-client.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import posthog from "posthog-js";
2+
3+
// only run on client side
4+
if (typeof window !== "undefined") {
5+
const apiKey = process.env.NEXT_PUBLIC_POSTHOG_KEY;
6+
7+
if (apiKey) {
8+
posthog.init(apiKey, {
9+
api_host: "/ingest",
10+
ui_host: "https://eu.posthog.com",
11+
person_profiles: "identified_only",
12+
capture_pageview: false, // we'll handle this manually
13+
capture_pageleave: true,
14+
debug: process.env.NODE_ENV === "development",
15+
session_recording: {
16+
recordCrossOriginIframes: true,
17+
},
18+
autocapture: {
19+
css_selector_allowlist: ["[data-track]", "button", "a[href]"],
20+
dom_event_allowlist: ["click", "submit"],
21+
},
22+
});
23+
}
24+
}

docs/next.config.mjs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,30 @@ const config = {
1111
generateEtags: true,
1212

1313
trailingSlash: false,
14+
skipTrailingSlashRedirect: true,
1415

1516
images: {
1617
formats: ["image/avif", "image/webp"],
1718
minimumCacheTTL: 31536000,
1819
},
1920

21+
async rewrites() {
22+
return [
23+
{
24+
source: "/ingest/static/:path*",
25+
destination: "https://eu-assets.i.posthog.com/static/:path*",
26+
},
27+
{
28+
source: "/ingest/:path*",
29+
destination: "https://eu.i.posthog.com/:path*",
30+
},
31+
{
32+
source: "/ingest/decide",
33+
destination: "https://eu.i.posthog.com/decide",
34+
},
35+
];
36+
},
37+
2038
headers: async () => {
2139
return [
2240
{
@@ -62,4 +80,4 @@ const config = {
6280
},
6381
};
6482

65-
export default withMDX(config);
83+
export default withMDX(config);

docs/package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
"types": "tsc --noEmit",
1111
"lint": "next lint"
1212
},
13+
"browserslist": [
14+
"chrome 64",
15+
"edge 79",
16+
"firefox 67",
17+
"opera 51",
18+
"safari 12"
19+
],
1320
"dependencies": {
1421
"@catppuccin/palette": "1.7.1",
1522
"@phosphor-icons/react": "2.1.10",
@@ -21,6 +28,8 @@
2128
"mermaid": "11.8.1",
2229
"next": "15.3.4",
2330
"ogl": "1.0.11",
31+
"posthog-js": "1.257.1",
32+
"posthog-node": "5.6.0",
2433
"react": "^19.1.0",
2534
"react-dom": "^19.1.0",
2635
"rehype-katex": "7.0.1",
@@ -39,4 +48,4 @@
3948
"eslint": "^8",
4049
"eslint-config-next": "15.3.4"
4150
}
42-
}
51+
}

docs/src/app/(home)/page.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Mermaid from "@/components/mdx/mermaid";
1313
import Aurora from "@/components/ui/aurora";
1414
import InstallScript from "@/components/home/install-script";
1515
import { createMetadata } from "@/lib/seo";
16+
import { TrackedLink } from "@/components/analytics/tracked-link";
1617

1718
export const metadata = createMetadata(
1819
"funnel",
@@ -83,17 +84,18 @@ export default function HomePage() {
8384
>
8485
try it anyway <ArrowRightIcon weight="bold" />
8586
</Link>
86-
<a
87+
<TrackedLink
8788
href="https://github.com/karol-broda/funnel"
8889
target="_blank"
8990
rel="noreferrer noopener"
91+
context="home_page_github_button"
9092
className={buttonVariants({
9193
color: "secondary",
9294
className: "px-6 py-3 text-base font-semibold",
9395
})}
9496
>
9597
⭐ judge my code
96-
</a>
98+
</TrackedLink>
9799
</div>
98100

99101
<div className="mt-12 flex flex-wrap justify-center items-center gap-4">

docs/src/app/docs/[[...slug]]/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { Metadata } from "next";
1616
import LastModified from "@/components/mdx/last-modified";
1717
import { getMDXComponents } from "@/mdx-components";
18+
import { DocTracker } from "@/components/docs/doc-tracker";
1819

1920
export default async function Page(props: {
2021
params: Promise<{ slug?: string[] }>;
@@ -40,6 +41,7 @@ export default async function Page(props: {
4041

4142
return (
4243
<DocsPage toc={page.data.toc} full={page.data.full}>
44+
<DocTracker docPath={page.url} docTitle={page.data.title} />
4345
<script
4446
type="application/ld+json"
4547
dangerouslySetInnerHTML={{

docs/src/app/layout.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { RootProvider } from "fumadocs-ui/provider";
44
import { Inter } from "next/font/google";
55
import type { ReactNode } from "react";
66
import { createMetadata, generateStructuredData, siteConfig } from "@/lib/seo";
7+
import { PostHogProviderWrapper } from "@/components/analytics/posthog-provider";
8+
import { PageTracker } from "@/components/analytics/page-tracker";
79

810
const inter = Inter({
911
subsets: ["latin"],
@@ -41,14 +43,17 @@ export default function Layout({ children }: { children: ReactNode }) {
4143
<meta name="color-scheme" content="dark light" />
4244
</head>
4345
<body>
44-
<RootProvider
45-
theme={{
46-
defaultTheme: "dark",
47-
storageKey: "theme",
48-
}}
49-
>
50-
{children}
51-
</RootProvider>
46+
<PostHogProviderWrapper>
47+
<PageTracker />
48+
<RootProvider
49+
theme={{
50+
defaultTheme: "dark",
51+
storageKey: "theme",
52+
}}
53+
>
54+
{children}
55+
</RootProvider>
56+
</PostHogProviderWrapper>
5257
</body>
5358
</html>
5459
);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use client";
2+
3+
import { usePageTracking } from "@/hooks/use-analytics";
4+
5+
export function PageTracker() {
6+
usePageTracking();
7+
return null;
8+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"use client";
2+
3+
import posthog from "posthog-js";
4+
import { PostHogProvider } from "posthog-js/react";
5+
import { ReactNode } from "react";
6+
7+
type PostHogProviderWrapperProps = {
8+
children: ReactNode;
9+
};
10+
11+
export function PostHogProviderWrapper({
12+
children,
13+
}: PostHogProviderWrapperProps) {
14+
// posthog is already initialized in instrumentation-client.ts
15+
// this provider just makes it available to React components
16+
17+
if (!process.env.NEXT_PUBLIC_POSTHOG_KEY) {
18+
return <>{children}</>;
19+
}
20+
21+
return <PostHogProvider client={posthog}>{children}</PostHogProvider>;
22+
}

0 commit comments

Comments
 (0)