-
Notifications
You must be signed in to change notification settings - Fork 50.1k
Description
The default onDefaultTransitionIndicator seems to sporadically stall view transitions. This does not occur with a custom onDefaultTransitionIndicator handler.
This occurs in Chrome, and Safari with the "Navigation API" feature flag enabled. This doesn't occur in Firefox because it doesn't support the Navigation API yet.
| Chrome | Safari |
|---|---|
Screen.Recording.2025-10-30.at.12.54.34.AM.mov |
Screen.Recording.2025-10-30.at.1.46.04.AM.mov |
The error message in development is a bit more descriptive:
Uncaught Error: A ViewTransition timed out because a Navigation stalled. This can happen if a Navigation is blocked on React itself. Such as if it's resolved inside useEffect. This can be solved by moving the resolution to useLayoutEffect.
at customizeViewTransitionError (react-dom-client.development.js:25585:20)
at react-dom-client.development.js:25783:24Caused by: TimeoutError: Transition was aborted because of timeout in DOM update
While the code example implements a custom router which also intercepts navigation events, it resolves them correctly inside useLayoutEffect(). Moreover, adding a custom onDefaultTransitionIndicator prevents the error, which suggests that the router code is correct, and that this is an issue within React with the default onDefaultTransitionIndicator.
Possibly related: #34662, #34676
React version: "experimental" (>19.3.0-experimental-9724e3e6-20251008)
- Specifically environments where
enableDefaultTransitionIndicatoris enabled.
Steps To Reproduce
- Visit https://async-react.dev/
- Make sure the request debugger sliders are set to 0s.
- Run the following snippet which simulates a click every 500ms for 200 clicks:
let shouldStopIteration = false;
window.onerror = (e) => {shouldStopIteration = true;};
for (let i = 0; i< 200; i++) {
if (shouldStopIteration) break;
const elts = document.querySelectorAll('[data-slot="item-actions"] button');
const ind= Math.floor(Math.random() * elts.length);
elts[ind].click();
await new Promise(r => setTimeout(r,500))
}- Observe that every now and then the page freezes, and we see an error in the console that the "ViewTransition timed out".
- Unfortunately, it is very inconsistent. So this may take multiple attempts or even a different timeout duration.
Link to code example: https://codesandbox.io/p/github/denk0403/async-react/view-transition-stall
The current behavior
The default onDefaultTransitionIndicator causes sporadic stalling of view transitions.
The expected behavior
The default onDefaultTransitionIndicator should not stall view transitions.