Skip to content

Commit ab73bf4

Browse files
committed
posthog migration
1 parent 94e2cbc commit ab73bf4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+354
-587
lines changed

apps/dashboard/.env.example

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ NEXT_PUBLIC_DASHBOARD_UPLOAD_SERVER="https://storage.thirdweb-dev.com"
3535
# - not required to build (unless testing contract search)
3636
NEXT_PUBLIC_TYPESENSE_CONTRACT_API_KEY=
3737

38-
# posthog API key
39-
# - not required for prod/staging
40-
NEXT_PUBLIC_POSTHOG_API_KEY="ignored"
41-
4238
# Stripe Customer portal
4339
NEXT_PUBLIC_STRIPE_KEY=
4440

@@ -108,4 +104,8 @@ STRIPE_SECRET_KEY=""
108104

109105
# required for server wallet management
110106
NEXT_PUBLIC_THIRDWEB_VAULT_URL=""
111-
NEXT_PUBLIC_ENGINE_CLOUD_URL=""
107+
NEXT_PUBLIC_ENGINE_CLOUD_URL=""
108+
109+
# posthog setup
110+
NEXT_PUBLIC_POSTHOG_KEY=""
111+
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import posthog from "posthog-js";
2+
3+
const NEXT_PUBLIC_POSTHOG_KEY = process.env.NEXT_PUBLIC_POSTHOG_KEY;
4+
5+
if (NEXT_PUBLIC_POSTHOG_KEY) {
6+
posthog.init(NEXT_PUBLIC_POSTHOG_KEY, {
7+
api_host: "/_ph",
8+
ui_host: "https://us.posthog.com",
9+
capture_pageview: "history_change",
10+
capture_pageleave: "if_capture_pageview",
11+
// disable exception capture (for now)
12+
capture_exceptions: false,
13+
// specifically disable autocapture (does not affect pageview capture)
14+
autocapture: false,
15+
debug: process.env.NODE_ENV === "development",
16+
});
17+
}

apps/dashboard/knip.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"@thirdweb-dev/service-utils",
1414
"@thirdweb-dev/vault-sdk",
1515
"@types/color",
16-
"fast-xml-parser"
16+
"fast-xml-parser",
17+
"posthog-node"
1718
]
1819
}

apps/dashboard/next.config.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ const baseNextConfig: NextConfig = {
146146
},
147147
async rewrites() {
148148
return [
149+
{
150+
source: "/_ph/static/:path*",
151+
destination: "https://us-assets.i.posthog.com/static/:path*",
152+
},
153+
{
154+
source: "/_ph/:path*",
155+
destination: "https://us.i.posthog.com/:path*",
156+
},
157+
{
158+
source: "/_ph/decide",
159+
destination: "https://us.i.posthog.com/decide",
160+
},
149161
{
150162
source: "/thirdweb.eth",
151163
destination: "/deployer.thirdweb.eth",
@@ -173,6 +185,8 @@ const baseNextConfig: NextConfig = {
173185
]),
174186
];
175187
},
188+
// This is required to support PostHog trailing slash API requests
189+
skipTrailingSlashRedirect: true,
176190
images: {
177191
dangerouslyAllowSVG: true,
178192
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",

apps/dashboard/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
"date-fns": "4.1.0",
6464
"fast-xml-parser": "^5.2.5",
6565
"fetch-event-stream": "0.1.5",
66-
"flat": "^6.0.1",
6766
"framer-motion": "12.17.0",
6867
"fuse.js": "7.1.0",
6968
"input-otp": "^1.4.1",
@@ -78,7 +77,8 @@
7877
"p-limit": "^6.2.0",
7978
"papaparse": "^5.5.3",
8079
"pluralize": "^8.0.0",
81-
"posthog-js": "1.67.1",
80+
"posthog-js": "1.252.0",
81+
"posthog-node": "5.1.0",
8282
"prettier": "3.5.3",
8383
"qrcode": "^1.5.3",
8484
"react": "19.1.0",
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"use client";
2+
3+
import posthog from "posthog-js";
4+
import { useEffect } from "react";
5+
import type { Account } from "../../@3rdweb-sdk/react/hooks/useApi";
6+
7+
const warnedMessages = new Set<string>();
8+
function warnOnce(message: string) {
9+
if (warnedMessages.has(message)) {
10+
return;
11+
}
12+
warnedMessages.add(message);
13+
console.warn(message);
14+
}
15+
16+
export function AccountIdentifier(props: {
17+
account: Pick<Account, "id" | "email">;
18+
}) {
19+
// eslint-disable-next-line no-restricted-syntax
20+
useEffect(() => {
21+
if (!posthog.__loaded) {
22+
warnOnce(
23+
"[DASHBOARD_ANALYTICS] is not initialized, cannot identify user",
24+
);
25+
return;
26+
}
27+
posthog.identify(props.account.id, {
28+
...(props.account.email ? { email: props.account.email } : {}),
29+
});
30+
}, [props.account.id, props.account.email]);
31+
return null;
32+
}
33+
34+
export function TeamIdentifier(props: {
35+
teamId: string;
36+
}) {
37+
// eslint-disable-next-line no-restricted-syntax
38+
useEffect(() => {
39+
if (!posthog.__loaded) {
40+
warnOnce(
41+
"[DASHBOARD_ANALYTICS] is not initialized, cannot identify team",
42+
);
43+
return;
44+
}
45+
posthog.group("team", props.teamId);
46+
}, [props.teamId]);
47+
return null;
48+
}
49+
50+
export function reset() {
51+
if (!posthog.__loaded) {
52+
warnOnce("[DASHBOARD_ANALYTICS] is not initialized, cannot reset");
53+
return;
54+
}
55+
posthog.reset();
56+
}

apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
"use client";
22

3+
import * as analytics from "@/analytics/dashboard.client";
34
import { Button } from "@/components/ui/button";
45
import { useStore } from "@/lib/reactive";
56
import { getSDKTheme } from "app/(app)/components/sdk-component-theme";
67
import { LazyConfigureNetworkModal } from "components/configure-networks/LazyConfigureNetworkModal";
78
import { CustomChainRenderer } from "components/selects/CustomChainRenderer";
89
import { mapV4ChainToV5Chain } from "contexts/map-chains";
9-
import { useTrack } from "hooks/analytics/useTrack";
1010
import { useAllChainsData } from "hooks/chains/allChains";
1111
import { useTheme } from "next-themes";
1212
import Image from "next/image";
@@ -156,6 +156,7 @@ export const CustomConnectWallet = (props: {
156156
onDisconnect={async () => {
157157
try {
158158
await doLogout();
159+
analytics.reset();
159160
} catch (err) {
160161
console.error("Failed to log out", err);
161162
}
@@ -259,18 +260,16 @@ function ConnectWalletWelcomeScreen(props: {
259260
</div>
260261
</div>
261262

262-
<TrackedAnchorLink
263+
<Link
263264
className="text-center font-semibold opacity-70 hover:no-underline hover:opacity-100"
264265
target="_blank"
265-
category="custom-connect-wallet"
266-
label="new-to-wallets"
267266
href="https://blog.thirdweb.com/web3-wallet/"
268267
style={{
269268
color: fontColor,
270269
}}
271270
>
272271
New to Wallets?
273-
</TrackedAnchorLink>
272+
</Link>
274273
</div>
275274
);
276275
}
@@ -303,36 +302,3 @@ export function useCustomConnectModal() {
303302
[connect, theme],
304303
);
305304
}
306-
307-
/**
308-
* A link component extends the `Link` component and adds tracking.
309-
*/
310-
function TrackedAnchorLink(props: {
311-
category: string;
312-
label?: string;
313-
trackingProps?: Record<string, string>;
314-
href: string;
315-
target?: string;
316-
children: React.ReactNode;
317-
className?: string;
318-
style?: React.CSSProperties;
319-
}) {
320-
const trackEvent = useTrack();
321-
const { category, label, trackingProps } = props;
322-
323-
const onClick = useCallback(() => {
324-
trackEvent({ category, action: "click", label, ...trackingProps });
325-
}, [trackEvent, category, label, trackingProps]);
326-
327-
return (
328-
<Link
329-
onClick={onClick}
330-
target={props.target}
331-
href={props.href}
332-
className={props.className}
333-
style={props.style}
334-
>
335-
{props.children}
336-
</Link>
337-
);
338-
}

apps/dashboard/src/app/(app)/account/components/AccountHeader.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"use client";
22

33
import { createTeam } from "@/actions/createTeam";
4+
import * as analytics from "@/analytics/dashboard.client";
5+
import { AccountIdentifier } from "@/analytics/dashboard.client";
46
import type { Project } from "@/api/projects";
57
import type { Team } from "@/api/team";
68
import { useDashboardRouter } from "@/lib/DashboardRouter";
@@ -35,6 +37,7 @@ export function AccountHeader(props: {
3537
const logout = useCallback(async () => {
3638
try {
3739
await doLogout();
40+
analytics.reset();
3841
if (wallet) {
3942
disconnect(wallet);
4043
}
@@ -77,6 +80,7 @@ export function AccountHeader(props: {
7780

7881
return (
7982
<div>
83+
<AccountIdentifier account={props.account} />
8084
<AccountHeaderDesktopUI {...headerProps} className="max-lg:hidden" />
8185
<AccountHeaderMobileUI {...headerProps} className="lg:hidden" />
8286

apps/dashboard/src/app/(app)/account/settings/AccountSettingsPage.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { confirmEmailWithOTP } from "@/actions/confirmEmail";
33
import { apiServerProxy } from "@/actions/proxies";
44
import { updateAccount } from "@/actions/updateAccount";
5+
import * as analytics from "@/analytics/dashboard.client";
56
import { useDashboardRouter } from "@/lib/DashboardRouter";
67
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
78
import type { ThirdwebClient } from "thirdweb";
@@ -46,6 +47,7 @@ export function AccountSettingsPage(props: {
4647
}}
4748
onAccountDeleted={async () => {
4849
await doLogout();
50+
analytics.reset();
4951
if (activeWallet) {
5052
disconnect(activeWallet);
5153
}

apps/dashboard/src/app/(app)/layout.tsx

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import "../../global.css";
22
import { DashboardRouterTopProgressBar } from "@/lib/DashboardRouter";
33
import { cn } from "@/lib/utils";
4-
import { PHProvider } from "lib/posthog/Posthog";
5-
import { PosthogHeadSetup } from "lib/posthog/PosthogHeadSetup";
6-
import { PostHogPageView } from "lib/posthog/PosthogPageView";
74
import type { Metadata } from "next";
85
import PlausibleProvider from "next-plausible";
96
import { Inter } from "next/font/google";
@@ -61,26 +58,19 @@ export default function RootLayout({
6158
customDomain="https://pl.thirdweb.com"
6259
selfHosted
6360
/>
64-
<PosthogHeadSetup />
6561
</head>
66-
<PHProvider disable_session_recording={true}>
67-
<PostHogPageView />
68-
<body
69-
className={cn(
70-
"bg-background font-sans antialiased",
71-
fontSans.variable,
72-
)}
73-
>
74-
<AppRouterProviders>{children}</AppRouterProviders>
75-
<DashboardRouterTopProgressBar />
76-
<NextTopLoader
77-
color="hsl(var(--foreground))"
78-
height={3}
79-
shadow={false}
80-
showSpinner={false}
81-
/>
82-
</body>
83-
</PHProvider>
62+
<body
63+
className={cn("bg-background font-sans antialiased", fontSans.variable)}
64+
>
65+
<AppRouterProviders>{children}</AppRouterProviders>
66+
<DashboardRouterTopProgressBar />
67+
<NextTopLoader
68+
color="hsl(var(--foreground))"
69+
height={3}
70+
shadow={false}
71+
showSpinner={false}
72+
/>
73+
</body>
8474
</html>
8575
);
8676
}

0 commit comments

Comments
 (0)