Repository navigation
fix: reload page once if hydration fails to fetch static assets - #3597
brillout-agent wants to merge 12 commits into
Conversation
With Client Routing, if fetching the page's static assets failed during hydration (e.g. flaky connection, or a new frontend was deployed while the page was loading), the server-rendered page stayed non-interactive. Vike now reloads the page in that case. To avoid an infinite reload loop, a page that was itself loaded by a reload isn't reloaded again (detected via the Navigation Timing API, so no storage is needed). Production only: in development such failures are usually caused by transform errors, which a reload doesn't fix. Fixes vikejs#3596 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013M9XEWwcvkeKwfcC9LCwgc
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013M9XEWwcvkeKwfcC9LCwgc
|
Is the fix accurate? Do we need to make the distinction whether it's a failure upon first page load or upon client-side navigation? |
Yes. I reproduced the issue in Retrying the
Yes. The recovery differs, and the code already distinguished the two cases before this PR (
The two paths combine without looping. I checked this in the browser: a client-side navigation whose target always fails leads to a full page load, then one reload, then Vike gives up (two page loads in total). Known limits:
Generated by Claude Code |
Since the reloaded page now handles the error like any other error (logs it and renders the error page) instead of rethrowing it, the playground, which doesn't define an error page, also logs "No error page defined." — which made the test fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013M9XEWwcvkeKwfcC9LCwgc
Reloading while offline replaces the (readable) server-side rendered page with the browser's offline error page. Instead, wait for the `online` event before reloading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013M9XEWwcvkeKwfcC9LCwgc
handleErrorFetchingStaticAssets() was called before the isRenderOutdated() check, so a rendering that was already superseded (e.g. the user navigated while the error page of the first render was being loaded) could reload/redirect the page, overriding the user's navigation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013M9XEWwcvkeKwfcC9LCwgc
…ch static assets `Failed to resolve module specifier` (chromium) and `Error resolving module specifier` (firefox) are thrown for unresolvable (e.g. bare) import specifiers, before any network request is made. Reloading the page (or redirecting upon client-side navigation) can't fix them: it only added a pointless page load before the same error. They're now handled like any other error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013M9XEWwcvkeKwfcC9LCwgc
Closes #3596
With Client Routing, when fetching the page's static assets fails during hydration (flaky connection, or a new frontend deployed while the page was loading), the server-rendered page stays non-interactive and the error surfaces as an unhandled rejection.
Vike now reloads the page in that case, but only once: a page that was itself loaded by a reload isn't reloaded again, so persistent failures can't cause a reload loop.
performance.getEntriesByType('navigation')[0].type === 'reload'), so nosessionStorage/localStorageflag is needed. If the type can't be determined (older browsers), Vike doesn't reload.Tests (
test/playground, production builds only):Docs: new section on
/deploy-sync, and an entry for it inllms.txt.Side note: with the
pageproxy of@brillout/test-e2e,page.unroute()is a silent no-op (Playwright assignsthis._routes, which lands on the proxy target), so the new tests route viapage.context(). The existingpage.unroute()call in the streamed-values test is affected too.🤖 Generated with Claude Code
https://claude.ai/code/session_013M9XEWwcvkeKwfcC9LCwgc