Skip to content

[CI] (97c6d9f) react-router/react-router-v7-project#2036

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-97c6d9f-react-router-react-router-v7-project
Closed

[CI] (97c6d9f) react-router/react-router-v7-project#2036
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-97c6d9f-react-router-react-router-v7-project

Conversation

@wizard-ci-bot

@wizard-ci-bot wizard-ci-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

Automated wizard CI run

Source: wizard-pr
Trigger ID: 97c6d9f
App: react-router/react-router-v7-project
App directory: apps/react-router/react-router-v7-project
Workbench branch: wizard-ci-97c6d9f-react-router-react-router-v7-project
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-06-23T16:31:05.584Z
Duration: 817.9s

@wizard-ci-bot

wizard-ci-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown
Author

PR Evaluation Report

Summary

This PR integrates PostHog into a React Router v7 framework-mode app ("CountryExplorer"). PostHog is initialized in entry.client.tsx with PostHogProvider, a reverse proxy is configured via Vite, error tracking is set up in the root ErrorBoundary, and nine custom events are captured across authentication and country interaction flows.

Files changed Lines added Lines removed
10 +136 -15

Confidence score: 4/5 👍

  • Capture called during render in country.tsx: posthog?.capture('country_detail_viewed', ...) is called directly in the component body, not in a useEffect or event handler. This fires on every re-render, producing duplicate events. Must be moved to a useEffect with appropriate dependencies. [CRITICAL]
  • Inconsistent distinct_id between login and signup: Login uses username as the distinct_id while signup uses newUser.id. The same user will get different distinct_ids depending on their entry path, fragmenting their data in PostHog. Both should use the same stable identifier (e.g., user ID). [CRITICAL]
  • PII (username) in event properties: username is passed as an event property in user_logged_in, user_logged_out, and user_signed_up capture calls. Per PostHog best practices, PII belongs in person properties (via identify()), not in capture() event properties. [MEDIUM]
  • Uses undocumented __add_tracing_headers option: The documented option is tracing_headers, not __add_tracing_headers (double-underscore prefix indicates private/internal API). [MEDIUM]

File changes

Filename Score Description
app/entry.client.tsx 4/5 PostHog init with PostHogProvider, reverse proxy host, and tracing headers. Uses undocumented __add_tracing_headers.
app/root.tsx 5/5 Error boundary with captureException — matches documented React Router framework mode pattern.
app/routes/countries.tsx 4/5 Five well-placed capture calls in event handlers with enriched properties. country_searched fires on every keystroke (noisy).
app/routes/country.tsx 2/5 Capture called during render body — will fire duplicate events on every re-render.
app/routes/login.tsx 2/5 Identify uses username as distinct_id instead of a stable user ID; PII in event properties.
app/routes/profile.tsx 5/5 Properly wraps logout with posthog.reset() and capture.
app/routes/signup.tsx 4/5 Identify uses newUser.id (correct), but inconsistent with login's use of username.
package.json 5/5 Correct packages added: posthog-js and @posthog/react.
vite.config.ts 5/5 Reverse proxy with /ingest/static, /ingest/array, and /ingest routes properly configured. SSR noExternal set correctly.
posthog-setup-report.md 3/5 Useful documentation but notes env vars need to be added to .env.example.

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes No syntax errors or missing dependencies that would prevent build
Preserves existing env vars & configs Yes Existing code and configs preserved; PostHog additions are additive
No syntax or type errors Yes All changed files have valid syntax and types
Correct imports/exports Yes All imports resolve correctly (posthog-js, @posthog/react)
Minimal, focused changes Yes Changes are focused on PostHog integration
Pre-existing issues None

Issues

  • Environment variables not documented: VITE_PUBLIC_POSTHOG_PROJECT_TOKEN, VITE_PUBLIC_POSTHOG_HOST, and VITE_PUBLIC_POSTHOG_ASSETS_HOST are required but no .env.example file was updated. The setup report acknowledges this as a TODO. [MEDIUM]

Other completed criteria

  • App builds without errors — dependencies added to package.json and imports are correct
  • SSR noExternal configured for posthog-js and @posthog/react in vite.config.ts
  • Existing app functionality (routing, auth, country browsing) preserved

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.393.0 and @posthog/react@^1.10.3 added to package.json
PostHog client initialized Yes Initialized in entry.client.tsx with PostHogProvider wrapping the app — correct pattern for React Router v7 framework mode
capture() Yes Nine meaningful capture calls across auth and country interaction flows
identify() No Inconsistent distinct_id: login uses username, signup uses newUser.id. No re-identification on session restore (page reload while logged in).
Error tracking Yes captureException(error) in root ErrorBoundary — matches documented pattern
Reverse proxy Yes Vite proxy configured with /ingest/static and /ingest/array routing to assets host, /ingest routing to PostHog host

Issues

  • Inconsistent distinct_id across login and signup: login.tsx calls posthog?.identify(username, ...) while signup.tsx calls posthog?.identify(newUser.id, ...). The same user gets different distinct_ids, fragmenting their profile. Both paths must use the same stable identifier (e.g., newUser.id or a database user ID). [CRITICAL]
  • No re-identification on session restore: Users who return via a persisted session (page reload while already logged in) are not re-identified. identify() should be called in the auth context when the session is restored from localStorage. [MEDIUM]
  • Uses __add_tracing_headers instead of tracing_headers: The documented config option is tracing_headers. The __ prefix indicates an internal API that may change without notice. [MEDIUM]

Other completed criteria

  • API key loaded from environment variable (import.meta.env.VITE_PUBLIC_POSTHOG_PROJECT_TOKEN)
  • API host correctly configured through reverse proxy (/ingest) with ui_host set
  • posthog.reset() called on logout in profile.tsx
  • Person properties set via identify() on signup (username, email)

PostHog insights and events ⚠️

Filename PostHog events Description
app/routes/signup.tsx user_signed_up Captures successful account creation with username property
app/routes/login.tsx user_logged_in Captures successful login with username property
app/routes/profile.tsx user_logged_out Captures logout with username, followed by posthog.reset()
app/routes/countries.tsx country_searched, country_region_filtered, country_claimed, country_liked, country_visited Captures search, filter, and engagement actions with enriched properties (country name, region)
app/routes/country.tsx country_detail_viewed Captures country detail page view — but called during render, causing duplicates
app/root.tsx captureException Error boundary captures unhandled exceptions

Issues

  • country_detail_viewed fires during render: posthog?.capture('country_detail_viewed', ...) is called in the component body, not in a useEffect. Every re-render triggers a duplicate event. Move to useEffect(() => { posthog?.capture(...) }, [country.name]). [CRITICAL]
  • PII in event properties: username is included as an event property in user_logged_in, user_logged_out, and user_signed_up. Usernames are personally identifiable and should only be set via identify() person properties, not in capture() event properties. [MEDIUM]
  • country_searched fires on every keystroke: This will produce a high volume of low-value events. Consider debouncing the capture or only firing on blur/submit. [LOW]

Other completed criteria

  • Events represent real user actions (signup, login, logout, search, filter, claim, like, visit, view detail)
  • Events enable product insights — funnels (signup → claim), trends (engagement over time), retention possible
  • Events include enriched properties (country name, region, already_claimed flag)
  • Event names are descriptive and use consistent snake_case convention

Reviewed by wizard workbench PR evaluator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants