Skip to content

Commit 8e3235a

Browse files
PostHog event pass (#246)
1 parent 78b8916 commit 8e3235a

File tree

9 files changed

+81
-38
lines changed

9 files changed

+81
-38
lines changed

.env.development

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ AUTH_URL="http://localhost:3000"
3434
# Sentry
3535
# SENTRY_BACKEND_DSN=""
3636
# NEXT_PUBLIC_SENTRY_WEBAPP_DSN=""
37-
SENTRY_ENVIRONMENT="dev"
37+
# SENTRY_ENVIRONMENT="dev"
3838
# NEXT_PUBLIC_SENTRY_ENVIRONMENT="dev"
3939
# SENTRY_AUTH_TOKEN=
4040

@@ -76,4 +76,6 @@ SOURCEBOT_TELEMETRY_DISABLED=true # Disables telemetry collection
7676

7777
# CONFIG_MAX_REPOS_NO_TOKEN=
7878
# NODE_ENV=
79-
# SOURCEBOT_TENANCY_MODE=single
79+
# SOURCEBOT_TENANCY_MODE=single
80+
81+
# NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=

Dockerfile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ARG SOURCEBOT_VERSION
99
# @see: https://posthog.com/tutorials/api-capture-events#authenticating-with-the-project-api-key
1010
ARG POSTHOG_PAPIK
1111
ARG SENTRY_ENVIRONMENT
12+
ARG SOURCEBOT_CLOUD_ENVIRONMENT
1213

1314
FROM node:20-alpine3.19 AS node-alpine
1415
FROM golang:1.23.4-alpine3.19 AS go-alpine
@@ -52,9 +53,11 @@ ARG POSTHOG_PAPIK
5253
ENV NEXT_PUBLIC_POSTHOG_PAPIK=$POSTHOG_PAPIK
5354
ARG SENTRY_ENVIRONMENT
5455
ENV NEXT_PUBLIC_SENTRY_ENVIRONMENT=$SENTRY_ENVIRONMENT
56+
ARG SOURCEBOT_CLOUD_ENVIRONMENT
57+
ENV NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT=$SOURCEBOT_CLOUD_ENVIRONMENT
5558
# Local args
56-
ARG SENTRY_WEBAPP_DSN
57-
ENV NEXT_PUBLIC_SENTRY_WEBAPP_DSN=$SENTRY_WEBAPP_DSN
59+
ARG NEXT_PUBLIC_SENTRY_WEBAPP_DSN
60+
ENV NEXT_PUBLIC_SENTRY_WEBAPP_DSN=$NEXT_PUBLIC_SENTRY_WEBAPP_DSN
5861
# -----------
5962

6063
RUN apk add --no-cache libc6-compat
@@ -104,6 +107,8 @@ ARG SOURCEBOT_VERSION
104107
ENV SOURCEBOT_VERSION=$SOURCEBOT_VERSION
105108
ARG POSTHOG_PAPIK
106109
ENV POSTHOG_PAPIK=$POSTHOG_PAPIK
110+
ARG SENTRY_ENVIRONMENT
111+
ENV SENTRY_ENVIRONMENT=$SENTRY_ENVIRONMENT
107112
# Local args
108113
# -----------
109114

packages/web/src/app/[domain]/components/settingsDropdown.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { useSession } from "next-auth/react";
3232
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
3333
import { signOut } from "next-auth/react"
3434
import { env } from "@/env.mjs";
35+
import posthog from "posthog-js";
3536

3637
interface SettingsDropdownProps {
3738
menuButtonClassName?: string;
@@ -94,7 +95,9 @@ export const SettingsDropdown = ({
9495
onClick={() => {
9596
signOut({
9697
redirectTo: "/login",
97-
});
98+
}).then(() => {
99+
posthog.reset();
100+
})
98101
}}
99102
>
100103
<LogOut className="mr-2 h-4 w-4" />

packages/web/src/app/[domain]/onboard/components/connectCodeHost.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import { useEffect, useState } from "react";
3+
import { useState } from "react";
44
import { CodeHostType } from "@/lib/utils";
55
import { getCodeHostIcon } from "@/lib/utils";
66
import {
@@ -15,8 +15,6 @@ import { OnboardingSteps } from "@/lib/constants";
1515
import { BackButton } from "./onboardBackButton";
1616
import { CodeHostIconButton } from "../../components/codeHostIconButton";
1717
import useCaptureEvent from "@/hooks/useCaptureEvent";
18-
import { useSession } from "next-auth/react";
19-
import posthog from "posthog-js";
2018
import SecurityCard from "@/app/components/securityCard";
2119

2220
interface ConnectCodeHostProps {
@@ -27,18 +25,6 @@ interface ConnectCodeHostProps {
2725
export const ConnectCodeHost = ({ nextStep, securityCardEnabled }: ConnectCodeHostProps) => {
2826
const [selectedCodeHost, setSelectedCodeHost] = useState<CodeHostType | null>(null);
2927
const router = useRouter();
30-
const { data: session } = useSession();
31-
32-
// Note: this is currently the first client side page that gets loaded after a user registers. If this changes, we need to update this.
33-
// @nocheckin
34-
useEffect(() => {
35-
if (session?.user) {
36-
posthog.identify(session.user.id, {
37-
email: session.user.email,
38-
name: session.user.name,
39-
});
40-
}
41-
}, [session?.user]);
4228

4329
const onCreated = useCallback(() => {
4430
router.push(`?step=${nextStep}`);

packages/web/src/app/components/logoutEscapeHatch.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { LogOutIcon } from "lucide-react";
22
import { signOut } from "@/auth";
3+
import posthog from "posthog-js";
4+
35
interface LogoutEscapeHatchProps {
46
className?: string;
57
}
@@ -14,6 +16,8 @@ export const LogoutEscapeHatch = ({
1416
"use server";
1517
await signOut({
1618
redirectTo: "/login",
19+
}).then(() => {
20+
posthog.reset();
1721
});
1822
}}
1923
>

packages/web/src/app/login/components/loginForm.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ import { SourcebotLogo } from "@/app/components/sourcebotLogo";
1313
import { TextSeparator } from "@/app/components/textSeparator";
1414
import useCaptureEvent from "@/hooks/useCaptureEvent";
1515
import DemoCard from "@/app/[domain]/onboard/components/demoCard";
16+
import Link from "next/link";
17+
import { env } from "@/env.mjs";
18+
19+
const TERMS_OF_SERVICE_URL = "https://sourcebot.dev/terms";
20+
const PRIVACY_POLICY_URL = "https://sourcebot.dev/privacy";
21+
1622
interface LoginFormProps {
1723
callbackUrl?: string;
1824
error?: string;
@@ -98,6 +104,9 @@ export const LoginForm = ({ callbackUrl, error, enabledMethods }: LoginFormProps
98104
]}
99105
/>
100106
</Card>
107+
{env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT !== undefined && (
108+
<p className="text-xs text-muted-foreground mt-8">By signing in, you agree to the <Link className="underline" href={TERMS_OF_SERVICE_URL} target="_blank">Terms of Service</Link> and <Link className="underline" href={PRIVACY_POLICY_URL} target="_blank">Privacy Policy</Link>.</p>
109+
)}
101110
</div>
102111
)
103112
}

packages/web/src/app/posthogProvider.tsx

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,25 @@ import { PostHogProvider as PHProvider } from 'posthog-js/react'
55
import { usePathname, useSearchParams } from "next/navigation"
66
import { Suspense, useEffect } from "react"
77
import { env } from '@/env.mjs'
8+
import { useSession } from 'next-auth/react'
9+
import { captureEvent } from '@/hooks/useCaptureEvent'
810

11+
// @see: https://posthog.com/docs/libraries/next-js#capturing-pageviews
912
function PostHogPageView() {
1013
const pathname = usePathname()
1114
const searchParams = useSearchParams()
1215
const posthog = usePostHog()
1316

14-
// Track pageviews
1517
useEffect(() => {
1618
if (pathname && posthog) {
1719
let url = window.origin + pathname
1820
if (searchParams.toString()) {
1921
url = url + `?${searchParams.toString()}`
2022
}
2123

22-
posthog.capture('$pageview', { '$current_url': url })
24+
captureEvent('$pageview', {
25+
$current_url: url,
26+
});
2327
}
2428
}, [pathname, searchParams, posthog])
2529

@@ -32,34 +36,55 @@ interface PostHogProviderProps {
3236
}
3337

3438
export function PostHogProvider({ children, disabled }: PostHogProviderProps) {
39+
const { data: session } = useSession();
40+
3541
useEffect(() => {
3642
if (!disabled && env.NEXT_PUBLIC_POSTHOG_PAPIK) {
43+
console.debug(`PostHog telemetry enabled. Cloud environment: ${env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT}`);
3744
posthog.init(env.NEXT_PUBLIC_POSTHOG_PAPIK, {
3845
// @see next.config.mjs for path rewrites to the "/ingest" route.
3946
api_host: "/ingest",
4047
person_profiles: 'identified_only',
4148
capture_pageview: false,
4249
autocapture: false,
43-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
44-
sanitize_properties: (properties: Record<string, any>, _event: string) => {
45-
// https://posthog.com/docs/libraries/js#config
46-
if (properties['$current_url']) {
47-
properties['$current_url'] = null;
48-
}
49-
if (properties['$ip']) {
50-
properties['$ip'] = null;
51-
}
52-
53-
return properties;
54-
}
50+
// In self-hosted mode, we don't want to capture the following
51+
// default properties.
52+
// @see: https://posthog.com/docs/data/events#default-properties
53+
property_denylist: env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT === undefined ? [
54+
'$current_url',
55+
'$pathname',
56+
'$session_entry_url',
57+
'$session_entry_host',
58+
'$session_entry_pathname',
59+
'$session_entry_referrer',
60+
'$session_entry_referring_domain',
61+
'$referrer',
62+
'$referring_domain',
63+
'$ip',
64+
] : []
5565
});
5666
} else {
57-
console.log("PostHog telemetry disabled");
67+
console.debug("PostHog telemetry disabled");
68+
}
69+
}, [disabled]);
70+
71+
useEffect(() => {
72+
if (!session) {
73+
return;
74+
}
75+
76+
// Only identify the user if we are running in a cloud environment.
77+
if (env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT !== undefined) {
78+
posthog.identify(session.user.id, {
79+
email: session.user.email,
80+
name: session.user.name,
81+
});
5882
}
59-
}, [disabled])
83+
}, [session]);
6084

6185
return (
6286
<PHProvider client={posthog}>
87+
{/* @see: https://github.com/vercel/next.js/issues/51581 */}
6388
<Suspense fallback={null}>
6489
<PostHogPageView />
6590
</Suspense>

packages/web/src/env.mjs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,26 @@ export const env = createEnv({
5050
// Misc UI flags
5151
SECURITY_CARD_ENABLED: booleanSchema.default('false'),
5252
},
53-
// @NOTE: Make sure you destructure all client variables in the
54-
// `experimental__runtimeEnv` block below.
53+
// @NOTE: Please make sure of the following:
54+
// - Make sure you destructure all client variables in
55+
// the `experimental__runtimeEnv` block below.
56+
// - Update the Dockerfile to pass these variables as build-args.
5557
client: {
5658
// PostHog
5759
NEXT_PUBLIC_POSTHOG_PAPIK: z.string().optional(),
5860

5961
// Misc
6062
NEXT_PUBLIC_SOURCEBOT_VERSION: z.string().default('unknown'),
6163
NEXT_PUBLIC_POLLING_INTERVAL_MS: numberSchema.default(5000),
64+
65+
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT: z.enum(["dev", "staging", "prod"]).optional(),
6266
},
6367
// For Next.js >= 13.4.4, you only need to destructure client variables:
6468
experimental__runtimeEnv: {
6569
NEXT_PUBLIC_POSTHOG_PAPIK: process.env.NEXT_PUBLIC_POSTHOG_PAPIK,
6670
NEXT_PUBLIC_SOURCEBOT_VERSION: process.env.NEXT_PUBLIC_SOURCEBOT_VERSION,
6771
NEXT_PUBLIC_POLLING_INTERVAL_MS: process.env.NEXT_PUBLIC_POLLING_INTERVAL_MS,
72+
NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT: process.env.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT,
6873
},
6974
skipValidation: process.env.SKIP_ENV_VALIDATION === "1",
7075
emptyStringAsUndefined: true,

packages/web/src/lib/posthogEvents.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ export type PosthogEventMap = {
244244
wa_demo_card_click: {},
245245
wa_demo_try_card_pressed: {},
246246
wa_share_link_created: {},
247+
//////////////////////////////////////////////////////////////////
248+
$pageview: {
249+
$current_url: string,
250+
},
247251
}
248252

249253
export type PosthogEvent = keyof PosthogEventMap;

0 commit comments

Comments
 (0)