Skip to content

Commit 6e8f3fb

Browse files
feat(website): add PostHog analytics
- Add PostHog provider with GDPR-friendly defaults (EU cloud, respects DNT) - Configure GitHub Actions to inject API key at build time - Update .gitignore to allow .env.example while ignoring .env.local
1 parent 9644d1e commit 6e8f3fb

File tree

7 files changed

+452
-14
lines changed

7 files changed

+452
-14
lines changed

.github/workflows/deploy-website.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ jobs:
3636

3737
- name: Build
3838
run: npm run build
39+
env:
40+
NEXT_PUBLIC_POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
41+
NEXT_PUBLIC_POSTHOG_HOST: https://eu.i.posthog.com
3942

4043
- name: Authenticate to Google Cloud
4144
uses: google-github-actions/auth@v2

website/.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# PostHog Analytics
2+
# Get your project API key from: https://app.posthog.com/project/settings
3+
NEXT_PUBLIC_POSTHOG_KEY=phc_your_project_api_key
4+
5+
# Use EU cloud for GDPR compliance (default)
6+
# Options: https://eu.i.posthog.com (EU) or https://us.i.posthog.com (US)
7+
NEXT_PUBLIC_POSTHOG_HOST=https://eu.i.posthog.com

website/.gitignore

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ yarn-debug.log*
3030
yarn-error.log*
3131
.pnpm-debug.log*
3232

33-
# env files (can opt-in for committing if needed)
34-
.env*
33+
# env files (keep .env.example for documentation)
34+
.env.local
35+
.env*.local
36+
.env.development.local
37+
.env.test.local
38+
.env.production.local
3539

3640
# vercel
3741
.vercel

website/app/layout.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Metadata } from "next";
22
import { Righteous, Source_Serif_4, JetBrains_Mono } from "next/font/google";
3+
import { PostHogProvider } from "@/components/PostHogProvider";
34
import "./globals.css";
45

56
const righteous = Righteous({
@@ -72,8 +73,10 @@ export default function RootLayout({
7273
<body
7374
className={`${righteous.variable} ${sourceSerif.variable} ${jetbrainsMono.variable} antialiased`}
7475
>
75-
<div className="grain-overlay" aria-hidden="true" />
76-
{children}
76+
<PostHogProvider>
77+
<div className="grain-overlay" aria-hidden="true" />
78+
{children}
79+
</PostHogProvider>
7780
</body>
7881
</html>
7982
);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"use client";
2+
3+
import posthog from "posthog-js";
4+
import { PostHogProvider as PHProvider } from "posthog-js/react";
5+
import { useEffect } from "react";
6+
7+
export function PostHogProvider({ children }: { children: React.ReactNode }) {
8+
useEffect(() => {
9+
if (
10+
typeof window !== "undefined" &&
11+
process.env.NEXT_PUBLIC_POSTHOG_KEY &&
12+
!posthog.__loaded
13+
) {
14+
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
15+
api_host:
16+
process.env.NEXT_PUBLIC_POSTHOG_HOST || "https://eu.i.posthog.com",
17+
person_profiles: "identified_only",
18+
capture_pageview: true,
19+
capture_pageleave: true,
20+
autocapture: true,
21+
persistence: "localStorage+cookie",
22+
// GDPR-friendly defaults
23+
respect_dnt: true,
24+
opt_out_capturing_by_default: false,
25+
});
26+
}
27+
}, []);
28+
29+
if (!process.env.NEXT_PUBLIC_POSTHOG_KEY) {
30+
return <>{children}</>;
31+
}
32+
33+
return <PHProvider client={posthog}>{children}</PHProvider>;
34+
}

0 commit comments

Comments
 (0)