Skip to content

[CI] (confirm-54-low-notes) next-js/15-app-router-saas#2410

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-confirm-54-low-notes-next-js-15-app-router-saas
Closed

[CI] (confirm-54-low-notes) next-js/15-app-router-saas#2410
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-confirm-54-low-notes-next-js-15-app-router-saas

Conversation

@wizard-ci-bot

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

Copy link
Copy Markdown

Automated wizard CI run

Source: manual
Trigger ID: confirm-54-low-notes
App: next-js/15-app-router-saas
App directory: apps/next-js/15-app-router-saas
Workbench branch: wizard-ci-confirm-54-low-notes-next-js-15-app-router-saas
Wizard branch: b98223d7c679b8f62ebb64f48ef09a1e8ba60724
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-07-03T18:05:34.943Z
Duration: 401.7s

YARA Scanner

✓ 216 tool calls scanned, 0 violations detected

No violations: ✓ 216 clean scans

@wizard-ci-bot

wizard-ci-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown
Author

PR Evaluation Report

Summary

This PR integrates PostHog into a Next.js 15 App Router SaaS application. It adds both client-side (posthog-js) and server-side (posthog-node) SDKs, initializes PostHog via instrumentation-client.ts, configures a reverse proxy through Next.js rewrites, adds a manual pageview tracker, captures several meaningful user events (auth, profile updates, security actions, sign-out), and includes posthog.reset() on logout. However, it critically omits posthog.identify() and will produce double pageviews.

Files changed Lines added Lines removed
10 +183 -8

Confidence score: 4/5 👍

  • Missing posthog.identify() entirely — The app has full auth (login/signup) but never calls posthog.identify(). All events remain anonymous, breaking the ability to tie events to known users across sessions and devices. The identifyServerUser helper is defined but never invoked. [CRITICAL]
  • Double pageviews on initial load — A manual PostHogPageview component captures , but `capture_pageview: false` is not set in `posthog.init()`. The SDK's default automatic pageview fires alongside the manual one, causing duplicate events on every initial page load. [CRITICAL]
  • Server-side PostHog helpers are dead codecaptureServerEvent() and identifyServerUser() in lib/posthog-server.ts are defined but never called by any committed file, making them unused scaffolding. [MEDIUM]

File changes

Filename Score Description
instrumentation-client.ts 3/5 Correctly initializes PostHog with env vars, reverse proxy, error tracking, and debug mode. Missing capture_pageview: false to prevent double pageviews.
next.config.ts 5/5 Properly configured reverse proxy with /ingest/static/* and /ingest/array/* routing to us-assets.i.posthog.com and catch-all to PostHog host.
package.json 5/5 Both posthog-js and posthog-node added with appropriate versions.
lib/posthog-server.ts 3/5 Well-structured server client with singleton pattern and helper functions, but none of the helpers are actually used anywhere.
components/posthog-pageview.tsx 3/5 Functional pageview component tracking pathname/searchParams changes, but will cause double pageviews without capture_pageview: false in init.
app/layout.tsx 5/5 Clean addition of PostHogPageview component to root layout.
app/(dashboard)/layout.tsx 4/5 Good sign-out tracking with posthog.reset(). Unused use import correctly removed.
app/(login)/login.tsx 3/5 Captures auth_form_submitted with useful properties but never calls posthog.identify().
app/(dashboard)/dashboard/general/page.tsx 4/5 Captures profile update with privacy-conscious properties (only has_name and email_domain).
app/(dashboard)/dashboard/security/page.tsx 5/5 Clean event tracking for password update and account deletion actions.

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes No syntax errors; all imports resolve to valid packages
Preserves existing env vars & configs Yes Existing configs preserved; only PostHog additions made. Removed comments in next.config.ts are non-functional.
No syntax or type errors Yes All TypeScript/JSX is valid
Correct imports/exports Yes posthog-js correctly imported in client components; posthog-node in server-only file
Minimal, focused changes Yes All changes relate to PostHog integration
Pre-existing issues None No pre-existing issues detected

Issues

  • Unused use import removal — The use import from React was removed from the dashboard layout. This is correct as use was not referenced in the file. [LOW]

Other completed criteria

  • Environment variables use NEXT_PUBLIC_ prefix for client-side access
  • server-only import guard on server-side PostHog module
  • Build configuration valid with proper rewrites and skipTrailingSlashRedirect

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.396.6 and posthog-node@^5.39.4 added to package.json
PostHog client initialized Yes Initialized in instrumentation-client.ts with env vars, reverse proxy, and error tracking — correct pattern for Next.js 15.3+
capture() Yes Multiple meaningful posthog.capture() calls across auth, profile, security, and navigation flows
identify() No Never called. The app has login/signup forms but no posthog.identify() is invoked on auth success. identifyServerUser() helper exists but is never used.
Error tracking Yes capture_exceptions: true set in init config enabling automatic exception autocapture
Reverse proxy Yes Properly configured via Next.js rewrites: /ingest/static/* and /ingest/array/*us-assets.i.posthog.com, /ingest/* → PostHog host

Issues

  • No posthog.identify() call anywhere: The app has full authentication (login, signup, user sessions) but never calls posthog.identify(). All captured events remain anonymous, making it impossible to build user-level funnels, retention analysis, or connect sessions across devices. The identifyServerUser() helper is defined in lib/posthog-server.ts but never invoked. The login form should call posthog.identify(userId, { email, name }) after successful authentication. [CRITICAL]
  • **Double events**: The `PostHogPageview` component manually fires `posthog.capture('')`, but `capture_pageview` is not set to `false` in `posthog.init()`. By default, `posthog-js` auto-captures a on initialization, causing two pageview events on the first page load. Add capture_pageview: false to the init config. [CRITICAL]
  • Server-side helpers are unused dead code: captureServerEvent() and identifyServerUser() are defined in lib/posthog-server.ts but no committed file calls them. They add complexity without value. [MEDIUM]

Other completed criteria

  • API key loaded from NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN environment variable
  • API host correctly configured via reverse proxy (/ingest) with ui_host fallback
  • posthog.reset() correctly called on sign-out
  • skipTrailingSlashRedirect: true set for reverse proxy compatibility
  • Both /static/* and /array/* asset routes configured for reverse proxy

PostHog insights and events ⚠️

Filename PostHog events Description
components/posthog-pageview.tsx `` Manual pageview tracking on route changes with pathname and query params
app/(login)/login.tsx auth_form_submitted Tracks signin/signup form submissions with auth_mode, invite status, redirect target, and email domain
app/(dashboard)/layout.tsx navigation_sign_out_clicked Captures sign-out action from user menu; also calls posthog.reset()
app/(dashboard)/dashboard/general/page.tsx account_profile_updated Tracks profile form submission with has_name flag and email_domain
app/(dashboard)/dashboard/security/page.tsx password_update_submitted, account_deletion_submitted Captures security-critical actions with source context
instrumentation-client.ts captureException (auto) Automatic exception capture via capture_exceptions: true

Issues

  • No identify means events lack user association: Without posthog.identify(), all the well-crafted events above are anonymous and cannot be used for per-user funnels (e.g., signup → profile update → retention). [CRITICAL]

Other completed criteria

  • Events represent real user actions (auth, profile updates, security changes, sign-out)
  • Events enable product insights — could build signup funnel, security action trends, churn analysis (account deletion)
  • Events include relevant enrichment properties (auth_mode, source, has_invite, redirect_target, email_domain)
  • No PII in event properties — emails extracted to domain-only; names reduced to boolean has_name
  • Event names are descriptive and use consistent snake_case convention

Reviewed by wizard workbench PR evaluator

@wizard-ci-bot wizard-ci-bot Bot added the CI/CD label Jul 3, 2026
@wizard-ci-bot wizard-ci-bot Bot closed this Jul 3, 2026
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