Skip to content

[CI] (3f39e0e) react-router/saas-template - #4178

Closed
wizard-ci-bot[bot] wants to merge 3 commits into
mainfrom
wizard-ci-3f39e0e-react-router-saas-template
Closed

wizard-ci-bot[bot] wants to merge 3 commits into
mainfrom
wizard-ci-3f39e0e-react-router-saas-template

Conversation

@wizard-ci-bot

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

Copy link
Copy Markdown

Automated wizard CI run

Source: wizard-pr
Trigger ID: 3f39e0e
App: react-router/saas-template
App directory: apps/react-router/saas-template
Workbench branch: wizard-ci-3f39e0e-react-router-saas-template
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-09-23T22:22:59.204Z
Duration: 603.6s

YARA Scanner

✓ 272 tool calls scanned, 0 violations detected

No violations: ✓ 272 clean scans

@wizard-ci-bot

wizard-ci-bot Bot commented Sep 23, 2026

Copy link
Copy Markdown
Author

Now I have enough context to produce the full evaluation.


PR Evaluation Report

Summary

This PR integrates PostHog into a React Router v7 framework-mode SaaS template. It adds posthog-js and @posthog/react as dependencies, initializes PostHog in entry.client.tsx with a PostHogProvider and PostHogErrorBoundary, identifies users via a loader in the authenticated layout, calls posthog.reset() on logout, adds custom capture() calls across 10+ form submission handlers, updates CSP headers for PostHog, and documents env vars in .env.example.

Files changed Lines added Lines removed
20 +219 -27

Confidence score: 5/5 🧙

  • Missing ssr.noExternal in vite.config.ts: React Router v7 framework mode uses SSR. The docs explicitly state that posthog-js and @posthog/react must be listed in ssr.noExternal in vite.config.ts to avoid SSR bundling errors. This is missing. [MEDIUM]
  • identify() called in useEffect reacting to state: The identify() call in _authenticated-routes-layout.tsx is placed inside a useEffect that watches user.id, user.email, user.name. Per React SDK rules, analytics capture should happen in event handlers, not in useEffect reacting to state changes. However, identify on mount is a documented pattern for linking users on page load, so this is acceptable for identify specifically. [LOW]

File changes

Filename Score Description
app/entry.client.tsx 5/5 PostHog initialized with env vars, wrapped in PostHogProvider + PostHogErrorBoundary, conditional rendering when config missing
app/entry.server.tsx 5/5 CSP headers updated for connect-src, script-src, and worker-src to allow PostHog
.env.example 5/5 Documents VITE_PUBLIC_POSTHOG_PROJECT_TOKEN and VITE_PUBLIC_POSTHOG_HOST
package.json 5/5 Adds @posthog/react and posthog-js dependencies
app/routes/_authenticated-routes+/_authenticated-routes-layout.tsx 4/5 Identify with user.id + person properties; uses useEffect but acceptable for identify-on-load
app/features/organizations/layout/nav-user.tsx 5/5 Calls posthog.reset() on logout form submit
app/lib/posthog-logger.client.ts 4/5 Logger wrapper using valid posthog.logger.info API
Various form components (10 files) 5/5 Custom capture calls in onSubmit handlers for real user actions

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes Syntax is valid, dependencies added correctly. Minor concern about missing ssr.noExternal but the app may still build depending on import patterns
Preserves existing env vars & configs Yes All existing env vars preserved, CSP additions are additive
No syntax or type errors Yes All TypeScript/JSX is valid, optional chaining used correctly
Correct imports/exports Yes @posthog/react and posthog-js imports are correct for client-side usage
Minimal, focused changes Yes All changes relate to PostHog integration; some attribute reordering is cosmetic but harmless
Pre-existing issues None -

Issues

  • Missing ssr.noExternal for PostHog packages: React Router v7 framework mode docs state posthog-js and @posthog/react should be added to ssr: { noExternal: [...] } in vite.config.ts to prevent SSR bundling issues. This could cause server-side rendering failures. [MEDIUM]

Other completed criteria

  • Environment variables documented in .env.example
  • Build configuration (package.json) is valid with correct dependency additions
  • .gitignore updated to exclude .env file

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js (^1.434.12) and @posthog/react (^1.11.1) added to package.json
PostHog client initialized Yes posthog.init() called in entry.client.tsx with api_host, capture_exceptions, and defaults: "2026-05-30"
capture() Yes 11 meaningful posthog.capture() calls across form submissions
identify() Yes posthog.identify(user.id, { email, name }) in authenticated layout using stable user ID from auth system
Error tracking Yes PostHogErrorBoundary wrapping app + capture_exceptions config with unhandled errors/rejections
Reverse proxy No No reverse proxy configured via rewrites or middleware

Issues

  • No reverse proxy configured: The PR does not set up a reverse proxy for PostHog requests. This is recommended to avoid ad-blocker interception. The CSP updates are good but a reverse proxy (via React Router rewrites or Vercel config) would improve reliability. [MEDIUM]

Other completed criteria

  • API key loaded from environment variable (VITE_PUBLIC_POSTHOG_PROJECT_TOKEN)
  • API host loaded from environment variable (VITE_PUBLIC_POSTHOG_HOST)
  • posthog.reset() called on logout in nav-user.tsx
  • PostHogErrorBoundary properly wraps the app inside PostHogProvider
  • CSP headers updated to allow PostHog domains for script-src, connect-src, and worker-src
  • Helpful dev-mode errors thrown when env vars are missing

PostHog insights and events ✅

Filename PostHog events Description
entry.client.tsx captureException (via ErrorBoundary) Captures uncaught React errors and unhandled promise rejections
_authenticated-routes-layout.tsx identify Identifies authenticated users with stable user ID, email, and name as person properties
nav-user.tsx reset Resets PostHog identity on logout
cancel-or-modify-subscription-modal-content.tsx subscription_change_submitted Tracks subscription modifications with billing_period property
create-subscription-modal-content.tsx subscription_checkout_started Tracks new subscription creation with billing_period property
create-organization-form-card.tsx organization_created Tracks organization creation
danger-zone.tsx (org) organization_deletion_submitted Tracks organization deletion
general-organization-settings.tsx organization_settings_updated Tracks organization settings changes
invite-by-email-card.tsx team_member_invite_submitted Tracks team member email invitations
invite-link-card.tsx invite_link_created Tracks invite link generation
account-settings.tsx user_account_updated Tracks user account settings updates
danger-zone.tsx (user) user_account_deletion_submitted Tracks user account deletion
organization.tsx (onboarding) organization_onboarding_submitted Tracks onboarding organization step
user-account.tsx (onboarding) user_account_onboarding_submitted Tracks onboarding user account step
pastes.tsx paste_created Tracks paste creation

Issues

  • No critical or medium issues with event quality.

Other completed criteria

  • Events represent real user actions (signup, subscription, settings changes, deletion)
  • Events enable product insights (onboarding funnel, subscription funnel, retention via user actions)
  • Subscription events include billing_period property for breakdown analysis
  • No PII in capture() properties — email/name only in identify() person properties
  • Event names are descriptive, 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