Element View Transition API #5670
Replies: 1 comment
-
|
Just coming back to this as I've thought about this a lot since my initial proposal. This entire problem may just be solved by reacts ViewTransition component. That's not a global solution obviously, but at least in react, I suspect that you will be able to do something like <ViewTransition>
<Outlet />
</ViewTransition>And this will sort of just work. The downside is that you are forced into the transition with this approach, whereas with a router level approach, the transition becomes optional and something you can provide as an argument on navigation. I still suspect that providing some kind of argument on the route which defines the transition, and then having the outlet render that transition component would make the most sense to be framework agnostic and hoist the handling to the router, but I'm not sure how reasonable my above suggestions are for this. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
I wanted to create a document/discussion for how tanstack router might implement an API to support element level view transitions. The motivation behind this is the recent implementation and addition of this behind a flag in chrome 140, and the rationale that supporting element transitions in a routing library seems like an extremely reasonable place to do so, since we are often only swapping out portions of the application, and not necessarily the entire page.
This lends well to element transitions because we can simply animate the lowest non-replacing router matches children, allowing sections of a page to be animated while keeping the layout of the page static if it is not being replaced.
This proposal defines a rough, opt-in API surface for route-level transitions that integrates naturally with TanStack’s existing patterns, while enabling full use of Chrome’s new element-based transitions.
Note: This discussion is mostly relating to API design and not implementation details at this stage.
Disclaimer: AI was used in improving the writing of this proposal
View Transitions API.
Motivation
View transitions currently solve animation between pages, but at a cost. Currently, a document view transition overlays the entire document with the transition layer, which is then animated. this causes the entire page to be blocked from interaction while it is animating.
The element level transition API solves this by providing the animation at an element level (or in the router case, a match/outlet level). This allows us to animate sub-trees of the dom, while keeping layout related content such as headers, footers, etc, that exist across routes to remain interactive and opt out of animations.
For route-based applications, the most logical boundary to animate is the outlet of a route that remains mounted during navigation.
Proposed Additions
transitionComponent Route Option
transitionComponentaccepts either:If present, this component should wrap the child outlet of the route. This defines the transition boundary for its child routes.
💡This differs from pendingComponent and errorComponent, which wrap the route itself. In this case, the route provides a transition boundary for its children, not for itself. This is intentional — when a route is unmounted, it cannot animate its own exit, as the incoming route will (likely) not share a transition name/id, and would potentially define it's own transition/component/etc. Therefore, the logical approach is for a route to offer a transition context to its children rather than expect one.
From a type-level perspective, I would expect this to only exist on non-leaf routes, as it applies to it's children, and lead nodes do not have children
I do recognise that this could be confusing for a user, as it behaves differently to other functionality, but it seems reasonable in this case
Route.useRegisterTransition Hook, Component or HOC
Since transitionComponent cannot (should not) receive props other than children (consistent with other route components), an approach to creating a transitionComponent would be required. There are a few options that come to mind
Hook Approach with children prop
This approach is a hybrid of prop injection (children prop is easy to type manually) while relying on a hook to provide an inferred
ref callback.
Hook Approach with Outlet (or TransitionOutlet)
This approach doesn't require any types being manually defined, and does not inject props, but introduces two new concepts for registering an outlet which seems heavy handed (although better than injecting props)
HOC Approach
This approach would infer the types for ref and children (as well as creating a forward ref in older react versions) by using a HOC.
Suggestion
Personally I am leaning to
createTransitionComponentas it provides the least new features specifically for view transitions, while inferring all types. It also allows us to avoid manually creating a ForwardRef if the react version does not support it. The other options feel "clunky" in one way or another in my opinionGlobal Default Option: mode
Extend the defaultViewTransition configuration in createRouter with a mode field:
"element": Use the new element transition model. If a route doesn’t define transitionComponent, a
<div>will be used automatically."document": Maintain existing document-level transitions (current behavior).
This provides a clean global opt-in without changing existing projects.
Behavior Summary
defaultViewTransition.mode. Routes may add transitionComponent individually if desired.<div>automatically wraps the outlet.Route.useRegisterTransition()returns a ref callback for the transition element.document.startViewTransitionis unsupported.view-transition-*CSS for animations.Example Usage
In this example:
Additional Notes
Async loaders:
No special handling needed — transitions start once routes are ready to render, consistent with current behavior.
History / scroll restoration:
Unaffected. Standard router behavior continues to apply.
Nested transitions:
If multiple transition elements exist in nested routes, the browser’s View Transition API should handle coordination automatically (needs confirmation through testing).
Non-supporting browsers:
Detection and fallback to no-op at runtime.
Summary
This proposal introduces:
Beta Was this translation helpful? Give feedback.
All reactions