Skip to content

[CI] (dbf5526) next-js/15-pages-router-saas - #3187

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-dbf5526-next-js-15-pages-router-saas
Closed

[CI] (dbf5526) next-js/15-pages-router-saas#3187
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-dbf5526-next-js-15-pages-router-saas

Conversation

@wizard-ci-bot

@wizard-ci-bot wizard-ci-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

Automated wizard CI run

Source: wizard-pr
Trigger ID: dbf5526
App: next-js/15-pages-router-saas
App directory: apps/next-js/15-pages-router-saas
Workbench branch: wizard-ci-dbf5526-next-js-15-pages-router-saas
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-07-28T16:58:57.449Z
Duration: 481.9s

YARA Scanner

✓ 234 tool calls scanned, 0 violations detected

No violations: ✓ 234 clean scans

@wizard-ci-bot

wizard-ci-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown
Author

PR Evaluation Report

Summary

This PR integrates PostHog into a Next.js 15 Pages Router SaaS application. It adds both client-side (posthog-js) and server-side (posthog-node) SDKs, initializes the client via instrumentation-client.ts, creates a server-side singleton helper, instruments 11 meaningful events across auth, team, and billing flows, and wires up user identification with proper reset() on logout.

Files changed Lines added Lines removed
15 +265 -17

Confidence score: 5/5 🧙

  • No reverse proxy configured — browser-side posthog-js requests will be intercepted by ad blockers. A Next.js rewrite or Vercel proxy should be set up. [MEDIUM]
  • posthog-setup-report.md is an unnecessary artifact committed to the repo. [LOW]

File changes

Filename Score Description
instrumentation-client.ts 5/5 New file: initializes posthog-js with env vars, error tracking, tracing headers, and dev guards
lib/posthog-server.ts 5/5 New file: server-side PostHog singleton with flush-per-call for short-lived API routes
package.json 5/5 Adds posthog-js and posthog-node dependencies
.env.example 5/5 Documents NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN and NEXT_PUBLIC_POSTHOG_HOST
components/header.tsx 5/5 Adds identify on refresh, capture on sign-out, and reset after logout
components/login.tsx 5/5 Identifies user with stable ID after successful sign-in/sign-up
pages/api/auth/sign-in.ts 4/5 Captures server-side sign-in event; returns user object for client-side identify
pages/api/auth/sign-up.ts 5/5 Captures sign-up, team_created, and invitation_accepted events
pages/api/stripe/checkout.ts 5/5 Captures checkout_completed with subscription status
pages/api/stripe/create-checkout.ts 5/5 Captures checkout_started with price_id
pages/api/stripe/customer-portal.ts 5/5 Captures customer_portal_opened
pages/api/account/update.ts 5/5 Captures account_updated
pages/api/team/invite.ts 5/5 Captures team_member_invited with role
pages/api/team/remove-member.ts 5/5 Captures team_member_removed
posthog-setup-report.md 2/5 Unnecessary documentation artifact — should not be committed

App sanity check ✅

Criteria Result Description
App builds and runs Yes Report confirms compilation passed; DB-dependent page-data collection fails due to pre-existing missing POSTGRES_URL
Preserves existing env vars & configs Yes Existing env vars untouched; sign-in/sign-up API responses are additive (extra user field)
No syntax or type errors Yes TypeScript compilation succeeded after nullable fix
Correct imports/exports Yes All imports resolve correctly — posthog-js for client, posthog-node for server
Minimal, focused changes Yes All code changes are PostHog-related; only the setup report is extraneous
Pre-existing issues Build requires POSTGRES_URL for page-data collection — not introduced by this PR

Issues

  • Setup report committed: posthog-setup-report.md is a CI artifact that shouldn't be in the codebase. Remove before merge. [LOW]

Other completed criteria

  • Environment variables documented in .env.example with clear names
  • Build configuration valid — package.json dependencies correctly added
  • All changes are relevant to PostHog integration

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.407.5 and posthog-node@^5.46.1 added to package.json
PostHog client initialized Yes instrumentation-client.ts uses posthog.init() with env vars, following the documented Next.js pattern
capture() Yes 11 events captured across client (sign-out) and server (sign-in, sign-up, checkout, team actions, etc.)
identify() Yes posthog.identify(String(user.id), { email, role }) on login and on page refresh; posthog.reset() on logout
Error tracking Yes capture_exceptions: true in client init enables browser exception autocapture
Reverse proxy No No reverse proxy configured — Next.js rewrites or Vercel proxy should be added

Issues

  • No reverse proxy: Browser-side posthog-js sends requests directly to us.i.posthog.com, which ad blockers will intercept. Configure a Next.js rewrite proxy or Vercel proxy to route through a first-party endpoint. [MEDIUM]

Other completed criteria

  • API key loaded from NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN environment variable, not hardcoded
  • API host loaded from NEXT_PUBLIC_POSTHOG_HOST environment variable
  • Client initialization is guarded — silently skips in production if env vars are missing, throws in development
  • Server-side singleton pattern with flushAt: 1 and flushInterval: 0 is correct for short-lived API routes
  • tracing_headers: [window.location.hostname] links client and server sessions
  • Identify uses stable database user ID (String(user.id)), not email
  • Email and role passed as person properties in identify(), not as event properties
  • posthog.reset() called after successful sign-out, before SWR cache clear
  • Header component re-identifies on page refresh when user is loaded via SWR

PostHog insights and events ✅

Filename PostHog events Description
components/header.tsx user_signed_out Captures sign-out before calling posthog.reset(); also handles identify on refresh
components/login.tsx identify Identifies user with stable ID and person properties after auth success
pages/api/auth/sign-in.ts user_signed_in Server-side capture with team_id on successful authentication
pages/api/auth/sign-up.ts user_signed_up, team_created, team_invitation_accepted Captures registration with signup source, plus contextual team events
pages/api/account/update.ts account_updated Server-side capture on profile update
pages/api/team/invite.ts team_member_invited Captures invitation with role and team_id
pages/api/team/remove-member.ts team_member_removed Captures member removal with team_id
pages/api/stripe/create-checkout.ts checkout_started Captures checkout initiation with price_id
pages/api/stripe/checkout.ts checkout_completed Captures successful checkout with subscription status
pages/api/stripe/customer-portal.ts customer_portal_opened Captures portal access with team_id
instrumentation-client.ts captureException (autocapture) Browser exceptions captured automatically via capture_exceptions: true

Issues

No issues.

Other completed criteria

  • All events represent real user actions in a SaaS product flow
  • Events enable product insights: signup → checkout funnel, retention via sign-ins, team growth via invites
  • Events include contextual properties (team_id, signup_source, invited_role, subscription_status, price_id)
  • No PII in event properties — email/name only in identify() person properties
  • Event names follow consistent snake_case convention and clearly describe the action

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