Skip to content

Commit 3ef9be2

Browse files
Add PostHog telemetry support
1 parent 9a8d17b commit 3ef9be2

18 files changed

+317
-43
lines changed

.dockerignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ README.md
77
!.next/static
88
!.next/standalone
99
.git
10-
.sourcebot
10+
.sourcebot
11+
.env.local

.env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
NEXT_PUBLIC_POSTHOG_KEY=phc_VFn4CkEGHRdlVyOOw8mfkoj1DKVoG6y1007EClvzAnS
2+
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
3+
NEXT_PUBLIC_POSTHOG_ASSET_HOST=https://us-assets.i.posthog.com
4+
NEXT_PUBLIC_POSTHOG_UI_HOST=https://us.posthog.com

Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ RUN yarn config set network-timeout 1200000
2222
RUN yarn --frozen-lockfile
2323
COPY . .
2424
ENV NEXT_TELEMETRY_DISABLED=1
25+
# @see: https://phase.dev/blog/nextjs-public-runtime-variables/
26+
ARG NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED=BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED
2527
RUN yarn run build
2628

2729
# ------ Runner ------
@@ -33,6 +35,9 @@ ENV DATA_DIR=/data
3335
ENV CONFIG_PATH=$DATA_DIR/config.json
3436
ENV DATA_CACHE_DIR=$DATA_DIR/.sourcebot
3537

38+
# Sourcebot collects anonymous usage data using [PostHog](https://posthog.com/). Uncomment this line to disable.
39+
# ENV SOURCEBOT_TELEMETRY_DISABLED=1
40+
3641
# Configure dependencies
3742
RUN apk add --no-cache git ca-certificates bind-tools tini jansson wget supervisor
3843

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,26 @@ zoekt will now index your repositories (at `HEAD`). By default, it will re-index
6565

6666
4. Go to `http://localhost:3000` - once a index has been created, you should get results.
6767

68-
69-
7068
## Building Sourcebot
7169

7270
TODO
7371

74-
## GitLab
72+
## Disabling Telemetry
73+
74+
By default, Sourcebot collects anonymous usage data using [PostHog](https://posthog.com/). You can disable this by setting the environment variable `SOURCEBOT_TELEMETRY_DISABLED` to `1` in the docker run command. Example:
75+
```sh
76+
docker run -e SOURCEBOT_TELEMETRY_DISABLED=1 ...stuff... ghcr.io/taqlaai/sourcebot:main
77+
```
78+
79+
80+
# GitLab
7581

7682
TODO
7783

78-
## BitBucket
84+
# BitBucket
7985

8086
TODO
8187

82-
### Todos
88+
# Todos
8389
- Add instructions on using GitLab and BitBucket
8490
- Add instructions on building Sourcebot locally

entrypoint.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/bin/sh
22
set -e
33

4-
54
# Check if CONFIG_PATH is set
65
if [ -z "$CONFIG_PATH" ]; then
76
echo "\e[33mWarning: CONFIG_PATH environment variable is not set.\e[0m"
@@ -35,4 +34,17 @@ else
3534
echo -e "\e[33mWarning: GitLab repositories will not be indexed since GITLAB_TOKEN was not set. If you are not using GitLab, disregard.\e[0m"
3635
fi
3736

37+
# Update nextjs public env variables w/o requiring a rebuild.
38+
# @see: https://phase.dev/blog/nextjs-public-runtime-variables/
39+
40+
# Infer NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED if it is not set
41+
if [ -z "$NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED" ] && [ ! -z "$SOURCEBOT_TELEMETRY_DISABLED" ]; then
42+
export NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED="$SOURCEBOT_TELEMETRY_DISABLED"
43+
fi
44+
45+
find /app/public /app/.next -type f -name "*.js" |
46+
while read file; do
47+
sed -i "s|BAKED_NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED|${NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED}|g" "$file"
48+
done
49+
3850
exec supervisord -c /etc/supervisor/conf.d/supervisord.conf

next.config.mjs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
/** @type {import('next').NextConfig} */
22
const nextConfig = {
3-
output: "standalone"
3+
output: "standalone",
4+
5+
// @see : https://posthog.com/docs/advanced/proxy/nextjs
6+
async rewrites() {
7+
return [
8+
{
9+
source: "/ingest/static/:path*",
10+
destination: `${process.env.NEXT_PUBLIC_POSTHOG_ASSET_HOST}/static/:path*`,
11+
},
12+
{
13+
source: "/ingest/:path*",
14+
destination: `${process.env.NEXT_PUBLIC_POSTHOG_HOST}/:path*`,
15+
},
16+
{
17+
source: "/ingest/decide",
18+
destination: `${process.env.NEXT_PUBLIC_POSTHOG_HOST}/decide`,
19+
},
20+
];
21+
},
22+
// This is required to support PostHog trailing slash API requests
23+
skipTrailingSlashRedirect: true,
424
};
525

626
export default nextConfig;

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,20 @@
2727
"@tanstack/react-table": "^8.20.5",
2828
"@uiw/react-codemirror": "^4.23.0",
2929
"class-variance-authority": "^0.7.0",
30+
"client-only": "^0.0.1",
3031
"clsx": "^2.1.1",
3132
"escape-string-regexp": "^5.0.0",
3233
"http-status-codes": "^2.3.0",
3334
"lucide-react": "^0.435.0",
3435
"next": "14.2.6",
3536
"next-themes": "^0.3.0",
37+
"posthog-js": "^1.161.5",
3638
"react": "^18",
3739
"react-dom": "^18",
3840
"react-hook-form": "^7.53.0",
3941
"react-hotkeys-hook": "^4.5.1",
4042
"react-resizable-panels": "^2.1.1",
43+
"server-only": "^0.0.1",
4144
"sharp": "^0.33.5",
4245
"tailwind-merge": "^2.5.2",
4346
"tailwindcss-animate": "^1.0.7",

src/app/layout.tsx

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ import "./globals.css";
44
import { ThemeProvider } from "next-themes";
55
import { Suspense } from "react";
66
import { QueryClientProvider } from "./queryClientProvider";
7+
import { PHProvider } from "./posthogProvider";
8+
import dynamic from "next/dynamic";
79

810
const inter = Inter({ subsets: ["latin"] });
911

12+
const PostHogPageView = dynamic(() => import('./posthogPageView'), {
13+
ssr: false,
14+
})
15+
1016
export const metadata: Metadata = {
1117
title: "Sourcebot",
1218
description: "Sourcebot",
@@ -24,22 +30,25 @@ export default function RootLayout({
2430
suppressHydrationWarning
2531
>
2632
<body className={inter.className}>
27-
<ThemeProvider
28-
attribute="class"
29-
defaultTheme="system"
30-
enableSystem
31-
disableTransitionOnChange
32-
>
33-
<QueryClientProvider>
34-
{/*
35-
@todo : ideally we don't wrap everything in a suspense boundary.
36-
@see : https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
37-
*/}
38-
<Suspense>
39-
{children}
40-
</Suspense>
41-
</QueryClientProvider>
42-
</ThemeProvider>
33+
<PHProvider>
34+
<PostHogPageView />
35+
<ThemeProvider
36+
attribute="class"
37+
defaultTheme="system"
38+
enableSystem
39+
disableTransitionOnChange
40+
>
41+
<QueryClientProvider>
42+
{/*
43+
@todo : ideally we don't wrap everything in a suspense boundary.
44+
@see : https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
45+
*/}
46+
<Suspense>
47+
{children}
48+
</Suspense>
49+
</QueryClientProvider>
50+
</ThemeProvider>
51+
</PHProvider>
4352
</body>
4453
</html>
4554
);

src/app/posthogPageView.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use client'
2+
3+
import { usePathname, useSearchParams } from "next/navigation";
4+
import { useEffect } from "react";
5+
import { usePostHog } from 'posthog-js/react';
6+
7+
export default function PostHogPageView(): null {
8+
const pathname = usePathname();
9+
const searchParams = useSearchParams();
10+
const posthog = usePostHog();
11+
useEffect(() => {
12+
// Track pageviews
13+
if (pathname && posthog) {
14+
let url = window.origin + pathname
15+
if (searchParams.toString()) {
16+
url = url + `?${searchParams.toString()}`
17+
}
18+
posthog.capture(
19+
'$pageview',
20+
{
21+
'$current_url': url,
22+
}
23+
)
24+
}
25+
}, [pathname, searchParams, posthog])
26+
27+
return null
28+
}

src/app/posthogProvider.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use client'
2+
import { NEXT_PUBLIC_POSTHOG_KEY, NEXT_PUBLIC_POSTHOG_UI_HOST, NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED } from '@/lib/environment.client'
3+
import posthog from 'posthog-js'
4+
import { PostHogProvider } from 'posthog-js/react'
5+
6+
if (typeof window !== 'undefined') {
7+
if (!NEXT_PUBLIC_SOURCEBOT_TELEMETRY_DISABLED) {
8+
posthog.init(NEXT_PUBLIC_POSTHOG_KEY!, {
9+
api_host: "/ingest",
10+
ui_host: NEXT_PUBLIC_POSTHOG_UI_HOST,
11+
person_profiles: 'identified_only',
12+
capture_pageview: false, // Disable automatic pageview capture, as we capture manually
13+
});
14+
} else {
15+
console.log("PostHog telemetry disabled");
16+
}
17+
}
18+
19+
export function PHProvider({
20+
children,
21+
}: {
22+
children: React.ReactNode
23+
}) {
24+
return <PostHogProvider client={posthog}>{children}</PostHogProvider>
25+
}

0 commit comments

Comments
 (0)