Fix intermittent blank page and profile setup redirect loop#11788
Merged
Conversation
RouterProvider (from react-router) initializes its state via useState(router.state). When the root route is lazy, the router starts with initialized=false/renderFallback=true, which causes _renderMatches to return null — an empty container. RouterProvider then escapes that null state via startTransition, but something in the concurrent route tree keeps the transition suspended long enough to produce a blank screen. Gate RouterProvider's mount on router.state.initialized. DataModeApplicationEntry subscribes to the router and shows a spinner until initialization completes, then mounts RouterProvider. By that point router.state has initialized=true, so useState(router.state) captures the ready state from the start and RouterProvider renders content immediately without a startTransition escape. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs caused users to be stuck on /my_profile/setup: 1. UpdateUserConProfile mutation did not return needs_update in its selection set. Apollo never wrote needs_update: false to the normalized cache after auto-save, so every subsequent client-side navigation read a stale needs_update: true and triggered a redirect. A page refresh fixed it by clearing the cache and fetching fresh data, hence the "goes away after a page refresh" symptom. Fix: add needs_update to the mutation response so Apollo updates the cache on every save. 2. The "Finish" button on the initial setup form was a plain <Link>, not a submit. If the user changed nothing, UpdateUserConProfile was never called, needs_update stayed true, and every navigation sent them back. Fix: change the button to fetcher.submit with _redirectTo so the action explicitly runs the mutation (setting needs_update=false) and then redirects to / on success. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Code Coverage Report: Only Changed Files listed
Minimum allowed coverage is |
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.
Summary
Blank page on initial load:
RouterProvider(fromreact-router) initializes its state viauseState(router.state). When the root route is lazy, the router starts withinitialized=false/renderFallback=true, causing_renderMatchesto returnnull— an empty container. RouterProvider then escapes that null state viastartTransition, but something in the concurrent route tree keeps the transition suspended long enough to produce a blank screen lasting 25+ seconds. Fix: gateRouterProvider's mount onrouter.state.initialized.DataModeApplicationEntrysubscribes to the router and shows a spinner until initialization completes, then mountsRouterProviderwith an already-initialized state.Redirect loop after new user profile setup: Two bugs conspired to keep users stuck on
/my_profile/setupafter completing login: (1)UpdateUserConProfilemutation did not returnneeds_updatein its selection set, so Apollo never wroteneeds_update: falseto the normalized cache after auto-save — every client-side navigation read staleneeds_update: trueand redirected back; (2) the "Finish" button on the setup form was a plain<Link>, so if the user changed nothing,UpdateUserConProfilewas never called at all. Fixed by addingneeds_updateto the mutation response and changing the Finish button tofetcher.submitwith a_redirectTofield so the action runs the mutation and redirects on success.Test plan
/my_profile/setup/my_profile/setup, click "Finish" without changing anything — should navigate to/without redirecting back/my_profile/setup, change a field (auto-save fires), then click "Finish" — should navigate to/without redirecting back🤖 Generated with Claude Code