Feat/oss readiness and analytics#39
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
7 issues found across 18 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="vercel.json">
<violation number="1" location="vercel.json:9">
P1: Missing required `/ingest/array/` rewrite for PostHog remote config. Without it, remote config requests (e.g., `/ingest/array/{token}/config.js`) fall through to the main API, which strips cache-control headers and can cause browsers to use stale SDK configuration.
Add a third rewrite before the catch-all `/ingest/:path*` rule:
```json
{
"source": "/ingest/array/:path*",
"destination": "https://us-assets.i.posthog.com/array/:path*"
}
```</violation>
</file>
<file name=".github/workflows/pr-size-labeler.yml">
<violation number="1" location=".github/workflows/pr-size-labeler.yml:9">
P2: Missing `contents: read` permission required by the action. Add `contents: read` to the permissions block.</violation>
<violation number="2" location=".github/workflows/pr-size-labeler.yml:14">
P2: Pin to the latest release v0.5.7 instead of v0.5.5 to get the Node 24 runtime update, security fixes, and updated dependencies.</violation>
</file>
<file name="src/components/PostHogPageView.tsx">
<violation number="1" location="src/components/PostHogPageView.tsx:14">
P1: This component duplicates PostHog's built-in SPA pageview tracking because `defaults: '2026-01-30'` in main.tsx already sets `capture_pageview: 'history_change'`. Every SPA navigation fires two `$pageview` events — one from PostHog's auto-capture and one from this useEffect — inflating pageview counts by 2x.
Either:
1. Remove this component and rely on PostHog's automatic `history_change` tracking (already active), or
2. Add `capture_pageview: false` to the PostHog init config in main.tsx to keep only this manual capture.</violation>
</file>
<file name="src/pages/AuthPage.tsx">
<violation number="1" location="src/pages/AuthPage.tsx:39">
P2: JWT payload decoding uses `atob` directly on a base64url segment, which fails for valid tokens and silently drops PostHog identification.</violation>
<violation number="2" location="src/pages/AuthPage.tsx:40">
P2: `posthog` is used inside `useEffect` but omitted from its dependency array, which can cause user identification to be missed when the client initializes after first render.</violation>
</file>
<file name="src/main.tsx">
<violation number="1" location="src/main.tsx:27">
P2: `PostHogProvider` is always rendered even when `posthog.init` is skipped, so it can receive an uninitialized client when `VITE_POSTHOG_KEY` is absent.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| }, | ||
| { | ||
| "source": "/ingest/:path*", | ||
| "destination": "https://us.i.posthog.com/:path*" |
There was a problem hiding this comment.
P1: Missing required /ingest/array/ rewrite for PostHog remote config. Without it, remote config requests (e.g., /ingest/array/{token}/config.js) fall through to the main API, which strips cache-control headers and can cause browsers to use stale SDK configuration.
Add a third rewrite before the catch-all /ingest/:path* rule:
{
"source": "/ingest/array/:path*",
"destination": "https://us-assets.i.posthog.com/array/:path*"
}Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At vercel.json, line 9:
<comment>Missing required `/ingest/array/` rewrite for PostHog remote config. Without it, remote config requests (e.g., `/ingest/array/{token}/config.js`) fall through to the main API, which strips cache-control headers and can cause browsers to use stale SDK configuration.
Add a third rewrite before the catch-all `/ingest/:path*` rule:
```json
{
"source": "/ingest/array/:path*",
"destination": "https://us-assets.i.posthog.com/array/:path*"
}
```</comment>
<file context>
@@ -1,5 +1,13 @@
+ },
+ {
+ "source": "/ingest/:path*",
+ "destination": "https://us.i.posthog.com/:path*"
+ },
{ "source": "/(.*)", "destination": "/" }
</file context>
| const location = useLocation(); | ||
| const posthog = usePostHog(); | ||
|
|
||
| useEffect(() => { |
There was a problem hiding this comment.
P1: This component duplicates PostHog's built-in SPA pageview tracking because defaults: '2026-01-30' in main.tsx already sets capture_pageview: 'history_change'. Every SPA navigation fires two $pageview events — one from PostHog's auto-capture and one from this useEffect — inflating pageview counts by 2x.
Either:
- Remove this component and rely on PostHog's automatic
history_changetracking (already active), or - Add
capture_pageview: falseto the PostHog init config in main.tsx to keep only this manual capture.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/components/PostHogPageView.tsx, line 14:
<comment>This component duplicates PostHog's built-in SPA pageview tracking because `defaults: '2026-01-30'` in main.tsx already sets `capture_pageview: 'history_change'`. Every SPA navigation fires two `$pageview` events — one from PostHog's auto-capture and one from this useEffect — inflating pageview counts by 2x.
Either:
1. Remove this component and rely on PostHog's automatic `history_change` tracking (already active), or
2. Add `capture_pageview: false` to the PostHog init config in main.tsx to keep only this manual capture.</comment>
<file context>
@@ -0,0 +1,21 @@
+ const location = useLocation();
+ const posthog = usePostHog();
+
+ useEffect(() => {
+ posthog?.capture('$pageview', {
+ $current_url: window.location.href,
</file context>
| pull-requests: write | ||
| steps: | ||
| - name: Add PR Size Label | ||
| uses: pascalgn/size-label-action@v0.5.5 |
There was a problem hiding this comment.
P2: Pin to the latest release v0.5.7 instead of v0.5.5 to get the Node 24 runtime update, security fixes, and updated dependencies.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/pr-size-labeler.yml, line 14:
<comment>Pin to the latest release v0.5.7 instead of v0.5.5 to get the Node 24 runtime update, security fixes, and updated dependencies.</comment>
<file context>
@@ -0,0 +1,23 @@
+ pull-requests: write
+ steps:
+ - name: Add PR Size Label
+ uses: pascalgn/size-label-action@v0.5.5
+ env:
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
</file context>
| jobs: | ||
| size-label: | ||
| runs-on: ubuntu-latest | ||
| permissions: |
There was a problem hiding this comment.
P2: Missing contents: read permission required by the action. Add contents: read to the permissions block.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/pr-size-labeler.yml, line 9:
<comment>Missing `contents: read` permission required by the action. Add `contents: read` to the permissions block.</comment>
<file context>
@@ -0,0 +1,23 @@
+jobs:
+ size-label:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
</file context>
| // Identify the user in PostHog using their JWT sub claim as the ID. | ||
| // The token is a JWT; we decode the payload to get the user ID. | ||
| try { | ||
| const payload = JSON.parse(atob(accessToken.split('.')[1])); |
There was a problem hiding this comment.
P2: JWT payload decoding uses atob directly on a base64url segment, which fails for valid tokens and silently drops PostHog identification.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/pages/AuthPage.tsx, line 39:
<comment>JWT payload decoding uses `atob` directly on a base64url segment, which fails for valid tokens and silently drops PostHog identification.</comment>
<file context>
@@ -31,6 +33,14 @@ export default function AuthPage() {
+ // Identify the user in PostHog using their JWT sub claim as the ID.
+ // The token is a JWT; we decode the payload to get the user ID.
+ try {
+ const payload = JSON.parse(atob(accessToken.split('.')[1]));
+ posthog?.identify(payload.sub, { email: payload.email });
+ } catch {
</file context>
| const payload = JSON.parse(atob(accessToken.split('.')[1])); | |
| const base64Url = accessToken.split('.')[1]; | |
| const payload = JSON.parse(atob(base64Url.replace(/-/g, '+').replace(/_/g, '/').padEnd(Math.ceil(base64Url.length / 4) * 4, '='))); |
| // The token is a JWT; we decode the payload to get the user ID. | ||
| try { | ||
| const payload = JSON.parse(atob(accessToken.split('.')[1])); | ||
| posthog?.identify(payload.sub, { email: payload.email }); |
There was a problem hiding this comment.
P2: posthog is used inside useEffect but omitted from its dependency array, which can cause user identification to be missed when the client initializes after first render.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/pages/AuthPage.tsx, line 40:
<comment>`posthog` is used inside `useEffect` but omitted from its dependency array, which can cause user identification to be missed when the client initializes after first render.</comment>
<file context>
@@ -31,6 +33,14 @@ export default function AuthPage() {
+ // The token is a JWT; we decode the payload to get the user ID.
+ try {
+ const payload = JSON.parse(atob(accessToken.split('.')[1]));
+ posthog?.identify(payload.sub, { email: payload.email });
+ } catch {
+ // Not a JWT or malformed — skip identification silently
</file context>
| <PostHogProvider client={posthog}> | ||
| <App /> | ||
| </PostHogProvider> |
There was a problem hiding this comment.
P2: PostHogProvider is always rendered even when posthog.init is skipped, so it can receive an uninitialized client when VITE_POSTHOG_KEY is absent.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/main.tsx, line 27:
<comment>`PostHogProvider` is always rendered even when `posthog.init` is skipped, so it can receive an uninitialized client when `VITE_POSTHOG_KEY` is absent.</comment>
<file context>
@@ -1,10 +1,31 @@
createRoot(document.getElementById('root')!).render(
<StrictMode>
- <App />
+ <PostHogProvider client={posthog}>
+ <App />
+ </PostHogProvider>
</file context>
| <PostHogProvider client={posthog}> | |
| <App /> | |
| </PostHogProvider> | |
| {POSTHOG_KEY ? ( | |
| <PostHogProvider client={posthog}> | |
| <App /> | |
| </PostHogProvider> | |
| ) : ( | |
| <App /> | |
| )} |
Summary by cubic
Adds PostHog analytics with SPA pageviews, user identification, and a Vercel proxy for ingestion; also streamlines OSS setup, docs, and templates to make contributions easier.
New Features
posthog-js; initializes only whenVITE_POSTHOG_KEYis set and opts out in dev.$pageviewon route changes viaPostHogPageView; app wrapped inPostHogProvider.subafter auth; resets analytics on logout to avoid session carry-over./ingest/*and/ingest/static/*to US PostHog endpoints..env.example: addedVITE_POSTHOG_KEYandVITE_POSTHOG_HOST(defaults to https://us.i.posthog.com).Refactors and Fixes
.env.local; clarified setup and removed emojis in docs andscripts/dev-setup.sh.useEffectdependency arrays.package-lock.jsonwithpackage.json.Written for commit ad6a9a6. Summary will update on new commits. Review in cubic