Skip to content

fix(onboarding): stop pinning new users to /app/new - #2890

Draft
posthog-eu[bot] wants to merge 2 commits into
mainfrom
posthog-self-driving/fixonboarding-stop-pinning-new-users-to-6ba976
Draft

fix(onboarding): stop pinning new users to /app/new#2890
posthog-eu[bot] wants to merge 2 commits into
mainfrom
posthog-self-driving/fixonboarding-stop-pinning-new-users-to-6ba976

Conversation

@posthog-eu

@posthog-eu posthog-eu Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

New signups with exactly one org and one app were pinned to /app/new: the resume guard re-fired on every navigation, and its only escape hatch lived in module-level state that a reload wiped — so Back, the breadcrumb, and sidebar tabs all bounced straight back.

Problem

  • Fires at the highest-stakes moment (first-app setup) for the post-cutoff 1-org/1-app cohort — Back / breadcrumb / sidebar all navigate and get instantly reverted, logged as dead clicks and rageclicks.
  • The escape hatch (allowOnboardingDashboardExploration) kept state in module-level variables, so a full reload wiped it and re-armed the trap.
  • app/new.vue re-ran init() on every currentOrganization change, re-showing the full-page loader and remounting AppOnboardingFlow — discarding whatever the user had typed.
  • Secondary: the org switcher's "Add organization" dropped existing users into the full new-user wizard (intent gate → MAU picker → logo → invite).

Changes

  • Non-sticky grant — persist the exploration grant in sessionStorage keyed by user id (in-memory fallback for SSR/privacy mode), so it survives a reload instead of re-arming.
  • Respect explicit exits — the guard now grants exploration when the user deliberately leaves /app/new (from.path === '/app/new'), carrying the pending resume app id, so Back / breadcrumb / sidebar tabs work.
  • No remount on org changeapp/new.vue watches the org gid and refreshes the app count without toggling isLoading, keeping AppOnboardingFlow mounted and preserving form input.
  • Compact additional-org path — the org switcher now offers a name-only create form (backend defaults estimated MAU and intent) instead of routing through the new-user wizard.

Test plan

  • bun run test:unit — added/updated coverage:
    • tests/onboarding-redirect.unit.test.ts — grant is per-user and survives a module reload (sessionStorage); graceful in-memory fallback when storage is unavailable.
    • tests/auth-sso-provisioning.unit.test.ts — driving the real navigation guard: an eligible user leaving /app/new is not bounced back, and stays put on subsequent navigations.
  • bun run typecheck:frontend and eslint/oxlint on the changed files pass.

Manual/visual verification of the fixed states (loader flash, remount, compact flow) requires a deployed environment with an authenticated post-cutoff new-user session; the affected behavior is documented in the linked report and the trap's break is covered by the guard-level test above.

Screenshots

None — behavior change; see test plan.

Checklist

  • My code follows the code style of this project and passes bun run lint:backend && bun run lint.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • My change has adequate E2E test coverage.
  • I have tested my code manually, and I have provided steps how to reproduce my tests

Created with PostHog Desktop from this inbox report.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Review in cubic

The resume guard added for post-cutoff single-org/single-app users
force-redirected them back to /app/new on every navigation, and the
only escape hatch lived in module-level state that a page reload wiped.

- Persist the exploration grant in sessionStorage keyed by user id so it
  survives a reload (with an in-memory fallback for restricted contexts).
- Grant exploration when the user deliberately leaves /app/new (Back,
  breadcrumb, sidebar tab) so the guard stops bouncing them back.
- Refresh app/new.vue's app count on org change without toggling the
  full-page loader, which used to remount the flow and wipe typed input.
- Give the org switcher a compact name-only path for creating an
  additional org instead of the full new-user wizard.

Generated-By: PostHog Code
Task-Id: cdd1ecee-fed7-40e9-832b-0173e86b56fb
@codspeed-hq

codspeed-hq Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 43 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing posthog-self-driving/fixonboarding-stop-pinning-new-users-to-6ba976 (0a69496) with main (60a641e)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

The compact create-org input reused the full-flow input's DOM id
(`onboarding-org-name-input`). Though the two are mutually exclusive at
runtime via v-if/v-else, the duplicate id tripped SonarCloud's
reliability gate. Rename the compact input's id/label to a distinct
`onboarding-org-name-compact`.

Generated-By: PostHog Code
Task-Id: cdd1ecee-fed7-40e9-832b-0173e86b56fb
@sonarqubecloud

sonarqubecloud Bot commented Aug 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants