Skip to content

[CI] (7c90ff9) next-js/15-app-router-saas#156

Closed
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-7c90ff9-next-js-15-app-router-saas
Closed

[CI] (7c90ff9) next-js/15-app-router-saas#156
wizard-ci-bot[bot] wants to merge 1 commit intomainfrom
wizard-ci-7c90ff9-next-js-15-app-router-saas

Conversation

@wizard-ci-bot
Copy link

@wizard-ci-bot wizard-ci-bot bot commented Jan 14, 2026

Automated wizard CI run

Trigger ID: 7c90ff9
App: next-js/15-app-router-saas
App directory: apps/next-js/15-app-router-saas
Workbench branch: wizard-ci-7c90ff9-next-js-15-app-router-saas
Wizard branch: feat-skill-based-integration
Examples branch: rearchitect-generator
PostHog (MCP) branch: feat-mcp-skill-deployment
Timestamp: 2026-01-14T21:16:47.787Z
Duration: 421.1s

@wizard-ci-bot
Copy link
Author

wizard-ci-bot bot commented Jan 14, 2026

Now I have all the information I need to provide a comprehensive PR evaluation. Let me write the review.


PR Evaluation Report

Summary

This PR adds PostHog analytics integration to a Next.js 15 App Router SaaS template. It implements client-side and server-side tracking, configures a reverse proxy for ad-block circumvention, and captures events across authentication, checkout, subscription, and user engagement flows.

Files changed Lines added Lines removed
16 +641 -38

Confidence score: 4/5 👍

  • Login tracking captures email in event properties: The sign_in_submitted and sign_up_submitted events include user email addresses as properties. While email is used for identify(), capturing it in event properties may violate PII policies depending on the organization's data governance requirements. [MEDIUM]
  • Account update captures name and email: The account_update_submitted event in general/page.tsx captures both name and email in event properties, which could be considered PII. [MEDIUM]
  • Missing posthog.flush() or shutdown() calls in API routes: Server-side tracking in checkout/route.ts and webhook/route.ts calls capture() but doesn't await flush() before the response is sent. Events may be lost due to serverless function lifecycle. [MEDIUM]
  • Unused formRef in login.tsx: The formRef is created and assigned to the form element but is never actually used, resulting in dead code. [LOW]

File changes

Filename Score Description
app/(dashboard)/dashboard/general/page.tsx 4/5 Adds PostHog tracking for account update form submission with name/email properties. Clean implementation using useCallback.
app/(dashboard)/dashboard/security/page.tsx 4/5 Adds tracking for password update and account deletion submissions. Properly wraps server actions.
app/(dashboard)/page.tsx 5/5 Refactors buttons into tracked client components. Clean extraction maintaining original functionality.
app/(dashboard)/pricing/page.tsx 5/5 Adds pricing page view tracker component and passes plan info to submit button. Minimal, focused change.
app/(dashboard)/pricing/pricing-page-tracker.tsx 5/5 New client component that fires pricing_page_viewed event on mount. Simple and correct.
app/(dashboard)/pricing/submit-button.tsx 4/5 Adds checkout tracking with plan name and price ID. Props type could use required vs optional clarity.
app/(dashboard)/tracked-buttons.tsx 5/5 New client component for tracked deploy and view code buttons. Preserves original button styling and behavior.
app/(login)/login.tsx 3/5 Adds auth tracking and user identification. Contains unused formRef and potentially sends duplicate events (on submit and on success).
app/api/stripe/checkout/route.ts 3/5 Adds server-side checkout tracking. Missing await posthog.flush() before redirect - events may be dropped.
app/api/stripe/webhook/route.ts 3/5 Adds server-side subscription tracking. Missing await posthog.flush() before response - events may be dropped.
instrumentation-client.ts 4/5 Client-side PostHog initialization using Next.js 15.3+ approach. Uses defaults: '2025-05-24' which is non-standard option name.
lib/posthog-server.ts 4/5 Server-side PostHog singleton with immediate flush settings. Proper pattern but shutdownPostHog() is exported but never used.
next.config.ts 5/5 Correctly configures reverse proxy rewrites for PostHog to bypass ad blockers. Includes skipTrailingSlashRedirect.
package.json 5/5 Adds posthog-js and posthog-node dependencies with appropriate versions.
pnpm-lock.yaml 5/5 Lock file updated with PostHog dependencies and their transitive dependencies.
posthog-setup-report.md 4/5 Helpful documentation of implemented events. Contains a truncated/invalid API key example.

App sanity check: 4/5 ✅

Criteria Result Description
App builds and runs Yes Dependencies are properly added, imports are correct, TypeScript types appear valid
Preserves existing env vars & configs Yes Only adds new PostHog env vars, preserves existing config structure
No syntax or type errors Yes All code follows TypeScript patterns, proper type annotations
Correct imports/exports Yes All imports resolve correctly, new modules properly exported
Minimal, focused changes Yes Changes are tightly scoped to PostHog integration, original app logic preserved

Issues

  • Unused formRef in login.tsx: The formRef is declared and assigned but never used for any purpose. Should be removed. [LOW]
  • Duplicate event capture in login flow: The login component captures events both on submission and on successful completion, which could result in duplicate sign_in_submitted events with different property values. [MEDIUM]

Other completed criteria

  • Clean separation of client and server components
  • Proper use of 'use client' directives
  • Consistent code style with existing codebase
  • No breaking changes to existing functionality
  • Original UI/UX preserved

PostHog implementation: 4/5 ✅

Criteria Result Description
PostHog SDKs installed Yes posthog-js@^1.321.2 and posthog-node@^5.21.0 added to dependencies
PostHog client initialized Yes Client initialized via instrumentation-client.ts with reverse proxy and exception capture
capture() Yes 13 distinct events captured across client and server-side code
identify() Yes User identification implemented in login flow using email as distinct ID
Error tracking Yes capture_exceptions: true enabled in client initialization
Reverse proxy Yes Next.js rewrites configured to route through /ingest to avoid ad blockers

Issues

  • Server-side events may be dropped: The API routes call posthog.capture() but don't call await posthog.flush() before sending responses. In serverless environments, this can cause events to be lost when the function terminates. Add await posthog.flush() after capture calls. [MEDIUM]
  • defaults option typo or non-standard: The client init uses defaults: '2025-05-24' which appears to be a non-standard option. The correct option for default behaviors is typically handled differently in posthog-js. [LOW]
  • Server client uses client env var: posthog-server.ts uses NEXT_PUBLIC_POSTHOG_KEY which is fine but conventionally server-side would use a non-public env var for API keys. [LOW]

Other completed criteria

  • Singleton pattern for server-side client prevents multiple instantiations
  • flushAt: 1 and flushInterval: 0 configured for immediate flushing
  • skipTrailingSlashRedirect properly set for PostHog API compatibility
  • Debug mode enabled in development environment
  • UI host properly separated from API host

PostHog insights and events: 4/5 ✅

Filename PostHog events Description
login.tsx sign_in_submitted, sign_up_submitted Captures authentication attempts with email, success status, and invite context
pricing-page-tracker.tsx pricing_page_viewed Top of funnel conversion tracking when user views pricing
submit-button.tsx checkout_started Captures checkout initiation with plan name and price ID for conversion analysis
general/page.tsx account_update_submitted Tracks profile updates with name and email properties
security/page.tsx password_update_submitted, account_delete_submitted Tracks security-related user actions
tracked-buttons.tsx deploy_button_clicked, view_code_clicked Homepage engagement tracking
checkout/route.ts stripe_checkout_completed, stripe_checkout_failed Server-side Stripe checkout completion with subscription details
webhook/route.ts subscription_updated, subscription_cancelled Server-side subscription lifecycle tracking

Issues

  • Missing failure tracking for auth: The sign-in/sign-up flow tracks submissions but doesn't explicitly track failures with error details, which would be useful for debugging authentication issues. [LOW]
  • No pageview tracking configured: While specific page events are captured, automatic pageview tracking (capture_pageview) isn't explicitly configured, relying on defaults. [LOW]

Other completed criteria

  • Events follow consistent naming convention (snake_case)
  • Properties include relevant context (plan names, price IDs, success status)
  • Funnel-ready event structure (pricing_page_viewed → checkout_started → stripe_checkout_completed)
  • Both client-side user actions and server-side system events captured
  • Subscription lifecycle fully covered (updated, cancelled)
  • User engagement on key CTAs tracked

Reviewed by wizard workbench PR evaluator

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