Skip to content

Commit 3f21667

Browse files
committed
chore: add basic default opt out instrumentation
1 parent e4e41d1 commit 3f21667

9 files changed

Lines changed: 147 additions & 2 deletions

File tree

apps/admin/.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,11 @@ RESEND_API_KEY=""
3838
# REFERRAL_PROGRAM_CLIENT_SECRET=""
3939
# NEXT_PUBLIC_REFREF_PROJECT_ID=""
4040
# NEXT_PUBLIC_REFREF_PROGRAM_ID=""
41+
42+
# PostHog Analytics (OPTIONAL)
43+
# Required only if you want to enable analytics and feature flags
44+
# Get your project key from: https://posthog.com/
45+
# Leave NEXT_PUBLIC_POSTHOG_KEY empty to disable PostHog entirely (no console errors)
46+
# Set NEXT_PUBLIC_POSTHOG_ENABLED to false to opt out of tracking while keeping PostHog initialized
47+
NEXT_PUBLIC_POSTHOG_KEY=""
48+
NEXT_PUBLIC_POSTHOG_ENABLED="true"

apps/admin/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import posthog from "posthog-js";
2+
import { env } from "./src/env";
3+
4+
// Only initialize PostHog if key is present and enabled
5+
if (env.NEXT_PUBLIC_POSTHOG_KEY) {
6+
if (env.NEXT_PUBLIC_POSTHOG_ENABLED) {
7+
posthog.init(env.NEXT_PUBLIC_POSTHOG_KEY, {
8+
api_host: "/ingest",
9+
ui_host: "https://us.posthog.com",
10+
defaults: "2025-05-24",
11+
capture_exceptions: true, // This enables capturing exceptions using Error Tracking
12+
debug: process.env.NODE_ENV === "development",
13+
loaded: (ph) => {
14+
if (!env.NEXT_PUBLIC_POSTHOG_ENABLED) {
15+
ph.opt_out_capturing();
16+
}
17+
},
18+
});
19+
}
20+
}
21+
22+
export { posthog };

apps/admin/next.config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ const config: NextConfig = {
1515
},
1616
];
1717
},
18+
async rewrites() {
19+
return [
20+
{
21+
source: "/ingest/static/:path*",
22+
destination: "https://us-assets.i.posthog.com/static/:path*",
23+
},
24+
{
25+
source: "/ingest/:path*",
26+
destination: "https://us.i.posthog.com/:path*",
27+
},
28+
];
29+
},
30+
skipTrailingSlashRedirect: true,
1831
transpilePackages: ["@refref/ui"],
1932
typescript: {
2033
ignoreBuildErrors: false,

apps/admin/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282
"nuqs": "2.4.3",
8383
"plugins": "link:better-auth/client/plugins",
8484
"postgres": "^3.4.5",
85+
"posthog-js": "^1.281.0",
86+
"posthog-node": "^5.10.4",
8587
"react": "^19.0.0",
8688
"react-aria-components": "^1.8.0",
8789
"react-day-picker": "8.10.1",

apps/admin/src/app/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { NuqsAdapter } from "nuqs/adapters/next/app";
77

88
import { TRPCReactProvider } from "@/trpc/react";
99
import { AuthUIProvider } from "@/components/providers/auth-ui-provider";
10+
import { PostHogProvider } from "@/components/providers/posthog-provider";
1011

1112
export const metadata: Metadata = {
1213
title: "RefRef - Referral Management Platform",
@@ -59,7 +60,9 @@ export default function RootLayout({
5960
>
6061
<TRPCReactProvider>
6162
<AuthUIProvider>
62-
<NuqsAdapter>{children}</NuqsAdapter>
63+
<PostHogProvider>
64+
<NuqsAdapter>{children}</NuqsAdapter>
65+
</PostHogProvider>
6366
</AuthUIProvider>
6467
</TRPCReactProvider>
6568
</ThemeProvider>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"use client";
2+
3+
import { PostHogProvider as PHProvider } from "posthog-js/react";
4+
import posthog from "posthog-js";
5+
import { useSession } from "@/lib/auth-client";
6+
import { useEffect } from "react";
7+
8+
function PostHogIdentifier() {
9+
const { data: session, isPending } = useSession();
10+
11+
useEffect(() => {
12+
// Skip if session is still loading
13+
if (isPending) {
14+
return;
15+
}
16+
17+
// Identify user when authenticated
18+
if (session?.user) {
19+
posthog.identify(session.user.id, {
20+
email: session.user.email,
21+
name: session.user.name,
22+
...(session.session?.activeOrganizationId && {
23+
activeOrganizationId: session.session.activeOrganizationId,
24+
}),
25+
});
26+
} else {
27+
// Reset PostHog when user logs out
28+
posthog.reset();
29+
}
30+
}, [session, isPending]);
31+
32+
return null;
33+
}
34+
35+
export function PostHogProvider({ children }: { children: React.ReactNode }) {
36+
return (
37+
<PHProvider client={posthog}>
38+
<PostHogIdentifier />
39+
{children}
40+
</PHProvider>
41+
);
42+
}

apps/admin/src/env.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ export const env = createEnv({
1818
GOOGLE_CLIENT_SECRET: z.string().min(1).default("google_client_secret"),
1919
REFERRAL_PROGRAM_CLIENT_ID: z.string().optional(),
2020
REFERRAL_PROGRAM_CLIENT_SECRET: z.string().optional(),
21-
NOTIFICATIONS_EMAIL_FROM: z.string().default("RefRef <notifications@mail.refref.ai>")
21+
NOTIFICATIONS_EMAIL_FROM: z
22+
.string()
23+
.default("RefRef <notifications@mail.refref.ai>"),
2224
},
2325

2426
/**
@@ -51,6 +53,11 @@ export const env = createEnv({
5153
.filter(Boolean)
5254
: [],
5355
),
56+
NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(),
57+
NEXT_PUBLIC_POSTHOG_ENABLED: z
58+
.enum(["true", "false"])
59+
.default("false")
60+
.transform((val) => val === "true"),
5461
},
5562

5663
/**
@@ -77,6 +84,8 @@ export const env = createEnv({
7784
NEXT_PUBLIC_ENABLED_SOCIAL_AUTH:
7885
process.env.NEXT_PUBLIC_ENABLED_SOCIAL_AUTH,
7986
NOTIFICATIONS_EMAIL_FROM: process.env.NOTIFICATIONS_EMAIL_FROM,
87+
NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY,
88+
NEXT_PUBLIC_POSTHOG_ENABLED: process.env.NEXT_PUBLIC_POSTHOG_ENABLED,
8089
},
8190
/**
8291
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially

pnpm-lock.yaml

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)