diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index cfac1ef..d6a7137 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -93,6 +93,8 @@ export default defineConfig({ outline: { level: [2, 3] }, }, vite: { + // the PostHog variables on Vercel use the NEXT_PUBLIC_ prefix + envPrefix: ['VITE_', 'NEXT_PUBLIC_'], server: { fs: { allow: ['..'] } }, ssr: { external: ['clipper-lib', 'svgo'] }, plugins: [ diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index e4ec198..bdd5483 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -11,5 +11,18 @@ export default { app.component('IconGrid', IconGrid); app.component('IconPage', IconPage); app.component('HomeShowcase', HomeShowcase); + + // Analytics: browser only, and only when a key is configured (so local dev and forks stay silent). + const key = import.meta.env.NEXT_PUBLIC_POSTHOG_KEY as string | undefined; + if (!import.meta.env.SSR && key) { + void import('posthog-js').then(({ default: posthog }) => { + posthog.init(key, { + api_host: (import.meta.env.NEXT_PUBLIC_POSTHOG_HOST as string | undefined) ?? 'https://eu.i.posthog.com', + // the `defaults` snapshot also turns on pageviews for client-side route changes + defaults: '2025-05-24', + person_profiles: 'identified_only', + }); + }); + } }, } satisfies Theme; diff --git a/docs/package.json b/docs/package.json index 4c4b1eb..0ca58c8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,6 +8,7 @@ "preview": "vitepress preview" }, "devDependencies": { + "posthog-js": "^1.434.0", "svgo": "^4.1.0", "vitepress": "^1.6.4", "vitepress-plugin-llms": "1.14.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a75b17..1bb6f67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ importers: docs: devDependencies: + posthog-js: + specifier: ^1.434.0 + version: 1.434.0 svgo: specifier: ^4.1.0 version: 4.1.0 @@ -747,6 +750,15 @@ packages: resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==} engines: {node: '>=22.13'} + '@posthog/browser-common@0.9.0': + resolution: {integrity: sha512-EWoVzs1vVY7ihpn8yOjj3jyjriHUEEMVSBNL/TW3hk09fTriWRe76vJXrRg0G0yjTYxHmtlSkNn4mOV24ZEzzA==} + + '@posthog/core@1.54.5': + resolution: {integrity: sha512-7N/Su3EnQpGaPSYgB7Ha0UQms47GObytCvuFjcKgSTEVlUWKO42hs38Zhb5O1S5VTxK1vPzavomieoGVrCOiZg==} + + '@posthog/types@1.412.2': + resolution: {integrity: sha512-taxTh8o6n7ZVlC8qBypZvF+6w7/18yNkS9XDiGCbutGTKqIljfzYi/7pumgwN3mcnl/n0e9A+JhF05+nLd4Xaw==} + '@resvg/resvg-js-android-arm-eabi@2.6.2': resolution: {integrity: sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA==} engines: {node: '>= 10'} @@ -1128,6 +1140,9 @@ packages: '@types/pngjs@6.0.5': resolution: {integrity: sha512-0k5eKfrA83JOZPppLtS2C7OUtyNAl2wKNxfyYl9Q5g9lPkgBl/9hNyAu6HuEH2J4XmIv2znEpkDd0SaZVxW6iQ==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -1402,6 +1417,9 @@ packages: resolution: {integrity: sha512-ufbM3smX/Jbnpk5wcQjzd1MgBpzmqfNETUAyZNrGwU9foRlyHoGzMMBBCRzEhQLBjZfFDE1W2ufPXX2vdWkV8Q==} engines: {node: '>=18'} + core-js@3.50.0: + resolution: {integrity: sha512-BRWgOLKkFeCgRudR6zrs8p9XJZcE14grzKMMssoYrk6krtuEZ7MTKPIY5RzOnqsEKIR9kst7wNzphttraT+Yqw==} + css-select@6.0.0: resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==} @@ -1483,6 +1501,9 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} + dompurify@3.4.15: + resolution: {integrity: sha512-EUBjM+B+lkDE41iE82DDSCfkoPGfXx8IxFxPMjNzm/Uk4xDet77rTN9wqlxlVg71kK7XGuUMv6wUxJUwwv+Xyw==} + domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -1602,6 +1623,9 @@ packages: picomatch: optional: true + fflate@0.4.9: + resolution: {integrity: sha512-zdxgIEddhfsyCaWpJ2SdXEP8ZMrKJ6+5jl4OupODcywU0IhRk6gdXuVGcPICyfx2H97hVK7xmJtRLPjkxAX8Vw==} + fix-dts-default-cjs-exports@1.0.1: resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} @@ -2052,6 +2076,17 @@ packages: resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} engines: {node: ^10 || ^12 || >=14} + posthog-js@1.434.0: + resolution: {integrity: sha512-4h3OrJhflC8WS4t0b/av7x2cNCzmktO6Ey5punQbzFMZRqj+Mwh6C2MWTwhO4w5HEIf2XWh4SiFokgWILHk9qw==} + peerDependencies: + '@types/react': '>=16.8.0' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + preact@10.29.8: resolution: {integrity: sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==} peerDependencies: @@ -2078,6 +2113,9 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + query-selector-shadow-dom@1.0.1: + resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} + querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -2491,6 +2529,12 @@ packages: resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==} engines: {node: '>=10'} + web-vitals@6.2.1: + resolution: {integrity: sha512-rLcLXA2sx6+9dE88NHFubwTtGxpK4yYBLj6qHPdFoCaLr0cXGb4efOqtKLlm4loGA4OEKHIQKMKzZkKyOh5ctw==} + + web-vitals@6.2.2: + resolution: {integrity: sha512-oto5x6dLEgrRqfcWed+pZEUb2q6ikbFmqF54CRDhI/QGbn+qxC49b4C4OkbH+kb9C3a8shpFD3SgR9kRcs80ZQ==} + webidl-conversions@5.0.0: resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} engines: {node: '>=8'} @@ -3113,6 +3157,17 @@ snapshots: '@pnpm/deps.graph-sequencer@1100.0.1': {} + '@posthog/browser-common@0.9.0': + dependencies: + '@posthog/core': 1.54.5 + '@posthog/types': 1.412.2 + + '@posthog/core@1.54.5': + dependencies: + '@posthog/types': 1.412.2 + + '@posthog/types@1.412.2': {} + '@resvg/resvg-js-android-arm-eabi@2.6.2': optional: true @@ -3369,6 +3424,9 @@ snapshots: dependencies: '@types/node': 26.5.1 + '@types/trusted-types@2.0.7': + optional: true + '@types/unist@3.0.3': {} '@types/web-bluetooth@0.0.21': {} @@ -3631,6 +3689,8 @@ snapshots: copy-anything@4.1.0: {} + core-js@3.50.0: {} + css-select@6.0.0: dependencies: boolbase: 1.0.0 @@ -3714,6 +3774,10 @@ snapshots: dependencies: domelementtype: 2.3.0 + dompurify@3.4.15: + optionalDependencies: + '@types/trusted-types': 2.0.7 + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 @@ -3894,6 +3958,8 @@ snapshots: optionalDependencies: picomatch: 4.0.7 + fflate@0.4.9: {} + fix-dts-default-cjs-exports@1.0.1: dependencies: magic-string: 0.30.21 @@ -4474,6 +4540,21 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + posthog-js@1.434.0: + dependencies: + '@posthog/browser-common': 0.9.0 + '@posthog/core': 1.54.5 + '@posthog/types': 1.412.2 + core-js: 3.50.0 + dompurify: 3.4.15 + fflate: 0.4.9 + preact: 10.29.8 + query-selector-shadow-dom: 1.0.1 + web-vitals: 6.2.2 + web-vitals-soft-navs: web-vitals@6.2.1 + transitivePeerDependencies: + - preact-render-to-string + preact@10.29.8: {} pretty-bytes@7.1.3: {} @@ -4490,6 +4571,8 @@ snapshots: punycode@2.3.1: optional: true + query-selector-shadow-dom@1.0.1: {} + querystringify@2.2.0: optional: true @@ -4975,6 +5058,10 @@ snapshots: xml-name-validator: 3.0.0 optional: true + web-vitals@6.2.1: {} + + web-vitals@6.2.2: {} + webidl-conversions@5.0.0: optional: true