Skip to content

[CI] (6b2dc8b) react-router/saas-template - #3743

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-6b2dc8b-react-router-saas-template
Closed

[CI] (6b2dc8b) react-router/saas-template#3743
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-6b2dc8b-react-router-saas-template

Conversation

@wizard-ci-bot

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

Copy link
Copy Markdown

Automated wizard CI run

Source: wizard-pr
Trigger ID: 6b2dc8b
App: react-router/saas-template
App directory: apps/react-router/saas-template
Workbench branch: wizard-ci-6b2dc8b-react-router-saas-template
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-09-01T16:04:50.858Z
Duration: 655.2s

YARA Scanner

✓ 270 tool calls scanned, 0 violations detected

No violations: ✓ 270 clean scans

@wizard-ci-bot

wizard-ci-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown
Author

Now I have all the information I need. Let me produce the evaluation.


PR Evaluation Report

Summary

This PR integrates PostHog into a React Router v7 (framework mode) SaaS template application. It adds the posthog-js SDK, initializes it via a client module imported from entry.client.tsx, implements user identification in the authenticated layout, adds posthog.reset() on logout, captures exceptions via an error boundary, and adds custom event captures across 10+ components covering billing, organization management, team invitations, and account settings. CSP headers are also updated.

Files changed Lines added Lines removed
17 +209 -16

Confidence score: 4/5 👍

  • Missing noExternal SSR config: The React Router v7 framework mode docs explicitly state that posthog-js must be added to ssr.noExternal in vite.config.ts to avoid SSR errors. This is missing and could cause server-side build/runtime failures when the posthog.client.ts module is imported in the authenticated layout's loader context. [MEDIUM]
  • useEffect for identify on user data: The posthog.identify() call is inside a useEffect in the authenticated layout. Per React rules, this is acceptable here as it synchronizes with an external system (PostHog). However, posthog is imported directly from the client module into a file that also exports a server loader, which may cause SSR bundling issues without noExternal. [MEDIUM]
  • No reverse proxy configured: No reverse proxy is set up, meaning client-side events may be blocked by ad blockers. [MEDIUM]

File changes

Filename Score Description
app/lib/posthog.client.ts 4/5 New PostHog initialization module with env var validation and error tracking config. Uses defaults: "2026-01-30" (slightly older date).
app/entry.client.tsx 5/5 Imports posthog client module to ensure initialization on hydration.
app/entry.server.tsx 4/5 Adds CSP directives for PostHog (connect-src, script-src, worker-src).
app/root.tsx 4/5 Adds CaptureRouteError component using dynamic import and captureException.
app/routes/_authenticated-routes+/_authenticated-routes-layout.tsx 3/5 Adds loader to fetch user data and identify() call. Imports posthog directly into a file with server exports.
app/features/organizations/layout/nav-user.tsx 5/5 Adds posthog.reset() on logout form submit. Well implemented.
app/features/billing/*.tsx 5/5 Captures billing events in form submit handlers with properties.
app/features/organizations/**/*.tsx 5/5 Captures org CRUD events with relevant properties.
app/features/user-accounts/settings/account/account-settings.tsx 5/5 Captures account update event.
.env.example 5/5 Documents PostHog env vars.
package.json 5/5 Adds posthog-js dependency.

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes Syntax is valid, dependencies added correctly. The SSR noExternal issue may cause runtime errors but the app should still build.
Preserves existing env vars & configs Yes All existing configurations preserved; PostHog additions are additive.
No syntax or type errors Yes All changed files use valid TypeScript/TSX syntax.
Correct imports/exports Yes All imports resolve correctly; posthog-js is the correct browser SDK package.
Minimal, focused changes Yes All changes relate to PostHog integration. No unnecessary modifications.
Pre-existing issues None

Issues

  • Missing ssr.noExternal for posthog-js: The React Router v7 framework mode docs require adding posthog-js to ssr.noExternal in vite.config.ts to prevent SSR bundling errors. The _authenticated-routes-layout.tsx file imports posthog.client.ts directly and also exports a server loader, which means Vite may try to bundle posthog-js for the server. Add ssr: { noExternal: ['posthog-js'] } to vite.config.ts. [MEDIUM]

Other completed criteria

  • Environment variables documented in .env.example
  • Build configuration valid (package.json properly updated)
  • CSP headers updated for PostHog compatibility (connect-src, script-src, worker-src)

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js ^1.424.0 added to package.json dependencies
PostHog client initialized Yes Initialized in app/lib/posthog.client.ts with posthog.init(), imported from entry.client.tsx
capture() Yes 12+ meaningful capture calls across billing, org management, team invites, and account settings
identify() Yes posthog.identify(posthogUser.id, { email, name }) called in authenticated layout using stable database user ID
Error tracking Yes captureException via error boundary in root.tsx; capture_exceptions config with unhandled errors and rejections
Reverse proxy No No reverse proxy configured; client-side events may be blocked by ad blockers

Issues

  • No reverse proxy: No Next.js rewrites, Vercel rewrites, or other reverse proxy configuration is set up. Client-side PostHog requests go directly to us.i.posthog.com (or whatever host is configured), which ad blockers may intercept. [MEDIUM]

Other completed criteria

  • API key loaded from environment variable (VITE_PUBLIC_POSTHOG_PROJECT_TOKEN)
  • Host correctly configured from environment variable (VITE_PUBLIC_POSTHOG_HOST)
  • posthog.reset() called on logout in nav-user.tsx
  • User identification uses stable database ID (user.id), not email
  • Person properties (email, name) correctly passed to identify()
  • Error boundary uses dynamic import to avoid SSR issues in root error boundary

PostHog insights and events ✅

Filename PostHog events Description
cancel-or-modify-subscription-modal-content.tsx subscription_change_requested, subscription_cancellation_requested Tracks subscription modifications and cancellations with price lookup key
create-subscription-modal-content.tsx checkout_started Tracks checkout initiation with price lookup key
create-organization-form-card.tsx organization_creation_submitted Tracks org creation
nav-user.tsx posthog.reset() Resets identity on logout
organization-switcher.tsx organization_switched Tracks org switching with org ID
danger-zone.tsx organization_deletion_submitted Tracks org deletion
general-organization-settings.tsx organization_settings_update_submitted Tracks settings updates with org ID
invite-by-email-card.tsx organization_invitation_email_submitted Tracks email invitations
invite-link-card.tsx invite_link_copied, invite_link_management_submitted Tracks link copying and management (create/regenerate/deactivate)
account-settings.tsx user_account_update_submitted Tracks account profile updates
root.tsx captureException Captures route-level errors
_authenticated-routes-layout.tsx posthog.identify() Identifies authenticated users

Issues

No issues.

Other completed criteria

  • Events represent real user actions across the full SaaS lifecycle (signup, billing, team management, settings)
  • Events enable product insights: can build funnels (org creation → subscription → team invite), retention, and billing analytics
  • Events include relevant properties (organization_id, price_lookup_key, action type)
  • No PII in event properties (email/name only in identify call as person properties)
  • Event names use consistent snake_case convention with descriptive action names

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