Show loading spinner throughout the full app boot sequence#11608
Merged
Conversation
- Inline CSS spinner in the HTML shell so something appears immediately, even before the JS bundle downloads - RouterLoadingOverlay component that stays visible until router.state.initialized is true, bridging the gap between the bootstrap Suspense phase and route components rendering - app_root_loading_content helper in ApplicationHelper (included by both the ERB layout and CmsRenderingContext) so the inline spinner is rendered consistently in both paths 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.
Purpose
There were two gaps in loading feedback during app boot: a blank screen before the JS bundle downloaded, and a ~1 second blank screen between the bootstrap Suspense spinner disappearing and the route components appearing on screen.
The root cause of the second gap was subtle:
createBrowserRouterstarts the initial navigation immediately when called, butrouter.state.initializedisfalseuntil the navigation completes. During that window,RouterProviderrenders nothing visible because the lazy root module and its loaders haven't finished yet — and the existing Suspense spinner had already gone away.Changes
💻 Engineer-facing
ApplicationHelper#app_root_loading_contentso bothcdn_spa_shell.html.erbandCmsRenderingContextuse the same markup.RouterLoadingOverlaycomponent rendered alongsideRouterProvider. It subscribes torouter.state.initializedviauseLayoutEffect(runs before RouterProvider's own layout effect, so it sees the buffered post-navigation state) and removes itself once the router is ready. No full-page overlay — just the same Bootstrap spinner, in normal flow, so it disappears at the same time content appears.Testing
Tested locally across cold loads and navigations. The spinner now appears immediately and stays visible until the page is ready.
🚢
🤖 Generated with Claude Code