View Transitions
Add native browser animations between document states during internal router navigation.
View Transitions add a native animation between two document states. In Boltdocs, enabling the feature makes internal router navigation use transitions automatically. Browsers without document.startViewTransition() continue with normal navigation without errors.
Enable automatic navigation
export default defineConfig({
experimental: {
viewTransitions: true,
},
})
You can also configure the types sent to the browser:
export default defineConfig({
experimental: {
viewTransitions: {
enabled: true,
types: ['page'],
},
},
})
Once enabled, Link, navbar, sidebar, and the router use the API automatically. You don't need to replace every link.
Add an explicit transition link
For an external page or a link that should activate independently, use TransitionLink from boltdocs/primitives:
import { TransitionLink } from 'boltdocs/primitives'
export function NextStep() {
return (
<TransitionLink href="/docs/guides/getting-started/configuration">
Continue to configuration
</TransitionLink>
)
}
TransitionLink explicitly triggers the transition for that link, even if the global experimental config is disabled. It preserves normal anchor behavior when the browser doesn't support the native API.
Run a transition around a change
Use useViewTransition() for state changes in external pages or custom controls:
import { useState } from 'react'
import { useViewTransition } from 'boltdocs/client'
export function PreviewToggle() {
const [preview, setPreview] = useState(false)
const transition = useViewTransition()
function toggle() {
transition.run(() => {
setPreview((value) => !value)
})
}
return (
<button type="button" onClick={toggle}>
{preview ? 'Show source' : 'Show preview'}
</button>
)
}
The hook is also directly invocable for compatibility:
transition(() => setOpen(true))
transition.start(() => setOpen(true))
The runner exposes transition.enabled, transition.supported, and transition.reducedMotion when a component needs to branch on the real capability instead of guessing. The callback can return a promise. The resulting handle exposes ready, updateCallbackDone, finished, and skipTransition when the browser provides them.
Directional transitions
Boltdocs tracks a history cursor while the app is running, so it knows whether a visitor moved forward or backward through the site. The direction is forwarded as a transition type alongside any configured types:
::view-transition-old(page) {
animation: fade-out 150ms ease;
}
::view-transition-new(page) {
animation: fade-in 150ms ease;
}
/* Backward navigation */
::view-transition-group(back) {
animation-duration: 220ms;
}
The type is added only once, and only when it is not already listed in your configuration, so a project that already declares forward is not affected.
Direction is derived from popstate, which is why the router stores a small index marker in history.state. Anchor-only navigation does not animate, because nothing on the page actually changes.
Respecting reduced motion
A view transition animates the entire document, so Boltdocs checks prefers-reduced-motion before starting one. When the visitor asks the operating system to reduce motion, the navigation happens immediately with no animation.
The check is live rather than read once at startup, so changing the system preference takes effect without a reload. The router and useViewTransition() both honor it, and transition.reducedMotion lets a custom control explain why the animation did not play.
See Experimental Features for the full opt-in setup.