[CI] (3393d57) react-router/saas-template#902
Closed
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
Closed
[CI] (3393d57) react-router/saas-template#902wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
Conversation
Author
|
Now I have all the context I need. Let me produce the evaluation. PR Evaluation ReportSummaryThis PR integrates PostHog analytics into a React Router v7 SaaS template. It adds client-side initialization with
Confidence score: 4/5 👍
File changes
App sanity check
|
| Criteria | Result | Description |
|---|---|---|
| App builds and runs | Yes | All syntax is valid, imports resolve, dependencies added |
| Preserves existing env vars & configs | Yes | No existing env vars or configs removed; middleware array extended properly |
| No syntax or type errors | Yes | TypeScript syntax correct across all files |
| Correct imports/exports | Yes | posthog-js, posthog-node, @posthog/react all imported correctly for their contexts |
| Minimal, focused changes | Yes | Changes are focused on PostHog integration with minor formatting adjustments |
| Pre-existing issues | None | No pre-existing issues observed |
Issues
- Missing PostHog env vars in .env.example:
VITE_PUBLIC_POSTHOG_PROJECT_TOKENandVITE_PUBLIC_POSTHOG_HOSTare used throughout the app but not documented in.env.example. New developers won't know they need these variables. [MEDIUM]
Other completed criteria
- All changes relate to PostHog integration
- Correct files modified for this framework (entry.client for init, root for middleware/error boundary, route files for events)
- Code follows existing codebase patterns (import ordering, naming conventions, TypeScript usage)
vite.config.tsSSR noExternal config is appropriate for React Router v7.gitignoreupdated to exclude.env
PostHog implementation ⚠️
| Criteria | Result | Description |
|---|---|---|
| PostHog SDKs installed | Yes | posthog-js@^1.360.2, posthog-node@^5.28.2, @posthog/react@^1.8.2 added to package.json |
| PostHog client initialized | Yes | posthog.init() called in entry.client.tsx with env vars and defaults: "2026-01-30"; server-side via posthog-node in middleware and webhook handlers |
| capture() | Yes | Multiple meaningful capture calls: user_login_requested, user_signup_requested, organization_created, contact_sales_submitted, plus server-side Stripe events |
| identify() | Yes | posthog.identify(currentUserId, { email: currentUserEmail }) called in authenticated sidebar layout |
| Error tracking | Yes | posthog.captureException(error) in root ErrorBoundary, though called during render instead of useEffect |
| Reverse proxy | No | No reverse proxy configured. The __add_tracing_headers option is for distributed tracing, not a reverse proxy. No Next.js rewrites or similar proxy setup present |
Issues
- No reverse proxy configured: The PR does not set up a reverse proxy to route PostHog requests through the app's domain. For a client-side app, this is recommended to prevent ad blockers from intercepting PostHog requests. The
__add_tracing_headersoption only adds tracing headers to fetch requests, it is not a reverse proxy. [MEDIUM] - captureException called during render: In
BaseErrorBoundary,posthog?.captureException(error)is called directly in the component function body. This is a side effect during render, which violates React best practices and will fire on every re-render, potentially sending duplicate error reports. It should be wrapped in auseEffect. [MEDIUM] - Stripe webhook hardcoded distinctId:
captureWebhookEventusesdistinctId: "stripe-webhook"for all events. This creates a single phantom user in PostHog instead of linking billing events to actual users. The organization ID or customer ID from the event could be used instead, or group analytics could link these to organizations. [MEDIUM]
Other completed criteria
- API key loaded from environment variable (
VITE_PUBLIC_POSTHOG_PROJECT_TOKEN) - API host correctly configured via
VITE_PUBLIC_POSTHOG_HOSTenv var - Server-side PostHog properly configured with
flushAt: 1andflushInterval: 0for short-lived request handlers PostHogProviderwraps the entire app inentry.client.tsx- Server-side middleware uses
withContext()to correlate sessions between client and server posthog.shutdown()called after server-side event capture
PostHog insights and events ⚠️
| Filename | PostHog events | Description |
|---|---|---|
app/routes/.../login.tsx |
user_login_requested |
Captures login attempts with method: "email" or method: "google" property |
app/routes/.../register.tsx |
user_signup_requested |
Captures signup attempts with method: "email" or method: "google" property |
app/routes/.../new.tsx |
organization_created |
Captures organization creation form submission |
app/routes/contact-sales.tsx |
contact_sales_submitted |
Captures contact sales form submission |
app/features/billing/stripe-event-handlers.server.ts |
checkout_completed, subscription_created, subscription_cancelled |
Server-side Stripe webhook events with billing properties |
app/root.tsx |
captureException |
Error tracking in root ErrorBoundary |
Issues
organization_createdandcontact_sales_submittedhave no properties: These events are captured with bareposthog.capture("event_name")with no enriching properties. Adding properties like organization name, plan type, or form context would make them more useful for analytics. [MEDIUM]
Other completed criteria
- Events represent real user actions (login, signup, org creation, contact sales, billing events)
- Events enable product insights (signup→org creation→checkout funnel possible)
- No PII in event properties (email only in
identify()person properties, not in capture calls) - Event names are descriptive and use consistent snake_case naming convention
- Server-side Stripe events include relevant billing properties (amount, currency, subscription_id, status)
Reviewed by wizard workbench PR evaluator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated wizard CI run
Source: wizard-pr
Trigger ID:
3393d57App:
react-router/saas-templateApp directory:
apps/react-router/saas-templateWorkbench branch:
wizard-ci-3393d57-react-router-saas-templateWizard branch:
release-please--branches--main--components--wizardContext Mill branch:
mainPostHog (MCP) branch:
masterTimestamp: 2026-03-17T00:42:40.429Z
Duration: 813.1s