[CI] (ca5a767) next-js/15-pages-router-saas#2744
Closed
wizard-ci-bot[bot] wants to merge 1 commit into
Closed
Conversation
Author
|
Now I have all the context needed. Let me produce the evaluation. PR Evaluation ReportSummaryThis PR integrates PostHog into a Next.js 15 Pages Router SaaS app with both client-side (
Confidence score: 4/5 👍
File changes
App sanity check
|
| Criteria | Result | Description |
|---|---|---|
| App builds and runs | Yes | No syntax or structural errors; valid TypeScript throughout |
| Preserves existing env vars & configs | Yes | Existing next.config.ts extended cleanly; no existing code removed |
| No syntax or type errors | Yes | All code is syntactically valid |
| Correct imports/exports | Yes | posthog-js imported client-side, posthog-node server-side; no cross-environment misuse |
| Minimal, focused changes | Yes | All changes serve PostHog integration; no unrelated edits |
| Pre-existing issues | None | N/A |
Issues
- Environment variables not in
.env.example:NEXT_PUBLIC_POSTHOG_PROJECT_TOKENandNEXT_PUBLIC_POSTHOG_HOSTare required but.env.examplewas not updated. Collaborators won't know these variables are needed. Add them to.env.examplewith placeholder values. [MEDIUM] - Invalid posthog-node config option:
enableExceptionAutocapture: trueinposthog-server.tsis not a recognizedposthog-nodeconfiguration option. It will be silently ignored but adds confusion. Remove it. [LOW]
Other completed criteria
- App builds without errors — no missing dependencies or broken syntax
- Existing app functionality fully preserved; env vars, configs, and routes intact
- Changes are minimal and focused exclusively on PostHog integration
- Correct separation of client (posthog-js) and server (posthog-node) imports
- Build configuration is valid — package.json deps and next.config.ts rewrites are correct
PostHog implementation ⚠️
| Criteria | Result | Description |
|---|---|---|
| PostHog SDKs installed | Yes | posthog-js@^1.399.2 and posthog-node@^5.40.0 added to package.json |
| PostHog client initialized | Yes | instrumentation-client.ts calls posthog.init() with env vars, reverse proxy host, defaults, and exception autocapture; imported from _app.tsx |
| capture() | Yes | 10+ meaningful capture calls across client and server for auth, billing, team, and account flows |
| identify() | No | Identify is implemented in auth and account flows, but client-side uses result.distinctId || data.email — raw email as fallback distinct_id causes fragmented profiles |
| Error tracking | Yes | captureException() in every catch block (client + server) plus capture_exceptions: true in client init |
| Reverse proxy | Yes | Next.js rewrites in next.config.ts correctly route /ingest/static/* and /ingest/array/* to us-assets.i.posthog.com and /ingest/* to us.i.posthog.com |
Issues
- Email fallback as distinct_id: In
login.tsxanddashboard/general.tsx,posthog.identify(result.distinctId || data.email, ...)uses raw email as a fallback distinct_id. If the server ever fails to returndistinctId, this creates fragmented person profiles. Remove the|| data.emailfallback — ifdistinctIdis missing, skip the identify call or handle the error. [MEDIUM] - Server
captureExceptionuses handler names as distinct_id: Insign-in.ts,sign-up.ts,update.ts, etc.,posthog.captureException(error, 'sign-in-handler')passes a descriptive label as the second argument. Inposthog-node, this argument isdistinctId, meaning exceptions are attributed to fake users like'sign-in-handler'. Pass the actual user's distinct_id or use the context-based API instead. [MEDIUM]
Other completed criteria
- API key correctly loaded from
NEXT_PUBLIC_POSTHOG_PROJECT_TOKENenvironment variable — not hardcoded - Host configured via reverse proxy (
/ingest) on client andNEXT_PUBLIC_POSTHOG_HOSTon server - Server client uses singleton pattern with
flushAt: 1, flushInterval: 0per Next.js docs posthog.reset()correctly called on sign-out inheader.tsx- Reverse proxy routes both
/static/*and/array/*to the assets origin as required
PostHog insights and events ✅
| Filename | PostHog events | Description |
|---|---|---|
components/login.tsx |
user_signed_in, user_signed_up |
Auth events with entrypoint, redirect target, and checkout context |
components/header.tsx |
user_signed_out, captureException |
Sign-out with source, plus reset and error tracking |
pages/dashboard/general.tsx |
account_updated, captureException |
Profile update with domain context and error tracking |
pages/dashboard/index.tsx |
billing_portal_opened, team_member_removed, team_member_invited, captureException |
Dashboard actions with plan, subscription, and team size properties |
pages/pricing.tsx |
pricing_cta_clicked, captureException |
CTA click with plan name, billing interval, trial days |
pages/api/auth/sign-in.ts |
user_signed_in, captureException |
Server-side auth with method, redirect, team context |
pages/api/auth/sign-up.ts |
user_signed_up, captureException |
Server-side signup with role, invite status, team context |
pages/api/auth/sign-out.ts |
user_signed_out, captureException |
Server-side sign-out using forwarded distinct_id |
pages/api/account/update.ts |
account_updated, captureException |
Server-side profile update with team context |
pages/api/stripe/create-checkout.ts |
checkout_session_created, captureException |
Checkout with price_id, team, plan details |
pages/api/stripe/webhook.ts |
stripe_subscription_updated, captureException |
Webhook processing with subscription status and event type |
pages/api/team/invite.ts |
team_member_invited, captureException |
Invite with role and team context |
pages/api/team/remove-member.ts |
team_member_removed, captureException |
Removal with member and team context |
Issues
- No critical or medium issues with event quality.
Other completed criteria
- Events represent real user actions across the full SaaS lifecycle (auth, billing, team management)
- Events enable product insights — can build signup→activation funnels, billing conversion, team growth analysis
- Events include enriched contextual properties (team_id, plan_name, role, billing_interval, etc.)
- No PII in event properties —
email_domainextraction is fine, full emails only in identify person properties - Event names use consistent
snake_caseconvention with descriptive, action-oriented names
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:
ca5a767App:
next-js/15-pages-router-saasApp directory:
apps/next-js/15-pages-router-saasWorkbench branch:
wizard-ci-ca5a767-next-js-15-pages-router-saasWizard branch:
release-please--branches--main--components--wizardContext Mill branch:
mainPostHog (MCP) branch:
masterTimestamp: 2026-07-11T00:35:13.281Z
Duration: 289.5s
YARA Scanner