From 288dfbcd214b972eae42647a21e69df933268def Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 21 Jan 2026 03:12:53 +0000 Subject: [PATCH 1/2] feat(docs): add PostHog analytics with search tracking - Add PostHog analytics component with EU region support - Track search queries, results, and clicks via custom Search override - Set up Vercel proxy rewrites to bypass ad-blockers - Support PUBLIC_POSTHOG_KEY environment variable - Auto-detect localhost for direct API access during development --- docs/astro.config.mjs | 4 +- docs/src/components/PostHog.astro | 113 ++++ docs/src/components/overrides/Head.astro | 20 + docs/src/components/overrides/Search.astro | 650 +++++++++++++++++++++ docs/vercel.json | 12 +- 5 files changed, 797 insertions(+), 2 deletions(-) create mode 100644 docs/src/components/PostHog.astro create mode 100644 docs/src/components/overrides/Head.astro create mode 100644 docs/src/components/overrides/Search.astro diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 5c9ff81..da03f45 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -13,10 +13,12 @@ export default defineConfig({ }, ], customCss: ["./src/styles/custom.css"], - // Component overrides for custom design + // Component overrides for custom design and analytics components: { Sidebar: "./src/components/overrides/Sidebar.astro", EditLink: "./src/components/overrides/EditLink.astro", + Head: "./src/components/overrides/Head.astro", + Search: "./src/components/overrides/Search.astro", }, // Autogenerate sidebar from directory structure // Contributors only need to add frontmatter to control ordering diff --git a/docs/src/components/PostHog.astro b/docs/src/components/PostHog.astro new file mode 100644 index 0000000..9d73320 --- /dev/null +++ b/docs/src/components/PostHog.astro @@ -0,0 +1,113 @@ +--- +/** + * PostHog Analytics Component + * + * Initializes PostHog for: + * - Page view tracking + * - Autocapture (clicks, form submits) + * - Session replay + * - Custom event tracking + * + * Uses a reverse proxy through Vercel to bypass ad-blockers. + * + * Environment Variables: + * - PUBLIC_POSTHOG_KEY: Your PostHog project API key (required) + * + * @see https://posthog.com/docs/libraries/astro + */ + +// Get PostHog key from environment variable +// In Astro, PUBLIC_ prefixed env vars are available on the client +const posthogKey = import.meta.env.PUBLIC_POSTHOG_KEY || ""; +--- + + diff --git a/docs/src/components/overrides/Head.astro b/docs/src/components/overrides/Head.astro new file mode 100644 index 0000000..21a8744 --- /dev/null +++ b/docs/src/components/overrides/Head.astro @@ -0,0 +1,20 @@ +--- +/** + * Custom Head Component with PostHog Analytics + * + * Extends Starlight's default Head component to inject PostHog analytics. + * PostHog is loaded early in the head to capture all page interactions. + * + * @see https://starlight.astro.build/guides/overriding-components/ + */ +import PostHog from "../PostHog.astro"; + +const { head } = Astro.locals.starlightRoute; +--- + +{ + head.map(({ tag: Tag, attrs, content }) => ( + + )) +} + diff --git a/docs/src/components/overrides/Search.astro b/docs/src/components/overrides/Search.astro new file mode 100644 index 0000000..3334bbb --- /dev/null +++ b/docs/src/components/overrides/Search.astro @@ -0,0 +1,650 @@ +--- +/** + * Custom Search Component with PostHog Analytics + * + * Extends Starlight's default Search component to track: + * - Search queries (debounced) + * - Search result clicks + * - Searches with no results + * + * @see https://starlight.astro.build/guides/overriding-components/ + */ +import project from "virtual:starlight/project-context"; + +const pagefindTranslations = { + placeholder: Astro.locals.t("search.label"), + ...Object.fromEntries( + Object.entries(Astro.locals.t.all()) + .filter(([key]) => key.startsWith("pagefind.")) + .map(([key, value]) => [key.replace("pagefind.", ""), value]), + ), +}; + +const dataAttributes: DOMStringMap = { + "data-translations": JSON.stringify(pagefindTranslations), +}; +if (project.trailingSlash === "never") + dataAttributes["data-strip-trailing-slash"] = ""; +--- + + + + + +
+ { + /* TODO: Make the layout of this button flexible to accommodate different word lengths. Currently hard-coded for English: "Cancel" */ + } + + { + import.meta.env.DEV ? ( +
+

{Astro.locals.t("search.devWarning")}

+
+ ) : ( +
+ + ) + } +
+
+
+ +{ + /** + * This is intentionally inlined to avoid briefly showing an invalid shortcut. + * Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the + * user agent is spoofed by some browsers when opening the devtools. + */ +} + + + + + + + diff --git a/docs/vercel.json b/docs/vercel.json index e37495e..eddacfc 100644 --- a/docs/vercel.json +++ b/docs/vercel.json @@ -2,5 +2,15 @@ "$schema": "https://openapi.vercel.sh/vercel.json", "framework": "astro", "buildCommand": "npm run build", - "outputDirectory": "dist" + "outputDirectory": "dist", + "rewrites": [ + { + "source": "/ingest/static/:path*", + "destination": "https://eu-assets.i.posthog.com/static/:path*" + }, + { + "source": "/ingest/:path*", + "destination": "https://eu.i.posthog.com/:path*" + } + ] } From 7e14689662af22aa923685f2b88c5fc7023d34d3 Mon Sep 17 00:00:00 2001 From: Adrian Henry Date: Wed, 21 Jan 2026 03:27:35 +0000 Subject: [PATCH 2/2] fix(docs): add TypeScript config for Starlight virtual modules - Add tsconfig.json with Starlight types - Add env.d.ts for pagefind types - Fix localhost detection for PostHog API host - Remove unused @ts-expect-error directive --- docs/src/components/overrides/Search.astro | 1 - docs/src/env.d.ts | 23 ++++++++++++++++++++++ docs/tsconfig.json | 18 +++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 docs/src/env.d.ts create mode 100644 docs/tsconfig.json diff --git a/docs/src/components/overrides/Search.astro b/docs/src/components/overrides/Search.astro index 3334bbb..bce5c6b 100644 --- a/docs/src/components/overrides/Search.astro +++ b/docs/src/components/overrides/Search.astro @@ -180,7 +180,6 @@ if (project.trailingSlash === "never") const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1)); onIdle(async () => { - // @ts-expect-error — Missing types for @pagefind/default-ui package. const { PagefindUI } = await import("@pagefind/default-ui"); new PagefindUI({ ...pagefindUserConfig, diff --git a/docs/src/env.d.ts b/docs/src/env.d.ts new file mode 100644 index 0000000..03ee87f --- /dev/null +++ b/docs/src/env.d.ts @@ -0,0 +1,23 @@ +/// +/// +/// +/// +/// + +declare module "@pagefind/default-ui" { + export class PagefindUI { + constructor(options: { + element?: string; + baseUrl?: string; + bundlePath?: string; + showImages?: boolean; + translations?: Record; + showSubResults?: boolean; + processResult?: (result: { + url: string; + sub_results: Array<{ url: string }>; + }) => void; + [key: string]: unknown; + }); + } +} diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 0000000..f81698d --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "types": ["@astrojs/starlight"], + "baseUrl": ".", + "paths": { + "virtual:starlight/*": [ + "./node_modules/@astrojs/starlight/virtual.d.ts", + "./node_modules/@astrojs/starlight/virtual-internal.d.ts" + ] + } + }, + "include": [ + "src/**/*", + ".astro/types.d.ts", + "node_modules/@astrojs/starlight/*.d.ts" + ] +}