Skip to content
brought to you byVoidZero
Private Beta:Void is currently in Private Beta. We do not recommend using it for mission-critical production workloads yet. Please back up your data regularly.

View Transitions

Pages mode supports the browser's native View Transition API for animated page transitions. When enabled, navigations are wrapped in document.startViewTransition(), which gives you a smooth cross-fade between pages by default. You can customize the effect entirely with CSS.

Enabling View Transitions

Pass viewTransitions: true to the adapter plugin:

ts
// vite.config.ts
export default defineConfig({
  plugins: [voidPlugin(), voidReact({ viewTransitions: true })],
});
ts
// vite.config.ts
export default defineConfig({
  plugins: [voidPlugin(), voidVue({ viewTransitions: true })],
});
ts
// vite.config.ts
export default defineConfig({
  plugins: [voidPlugin(), voidSvelte({ viewTransitions: true })],
});
ts
// vite.config.ts
export default defineConfig({
  plugins: [voidPlugin(), voidSolid({ viewTransitions: true })],
});

This enables view transitions for all navigations, including Link clicks, programmatic router.visit() calls, and browser back or forward.

Override the global setting on individual links:

tsx
{
  /* Disable transition for this link */
}
<Link href="/settings" viewTransition={false}>
  Settings
</Link>;

{
  /* Enable for just this link (even if globally disabled) */
}
<Link href="/about" viewTransition>
  About
</Link>;
vue
<!-- Disable transition for this link -->
<Link href="/settings" :view-transition="false">Settings</Link>

<!-- Enable for just this link (even if globally disabled) -->
<Link href="/about" view-transition>About</Link>
svelte
<!-- Disable transition for this link -->
<Link href="/settings" viewTransition={false}>Settings</Link>

<!-- Enable for just this link (even if globally disabled) -->
<Link href="/about" viewTransition>About</Link>
tsx
{
  /* Disable transition for this link */
}
<Link href="/settings" viewTransition={false}>
  Settings
</Link>;

{
  /* Enable for just this link (even if globally disabled) */
}
<Link href="/about" viewTransition>
  About
</Link>;

Or programmatically:

ts
router.visit('/about', { viewTransition: true });
router.visit('/settings', { viewTransition: false });

Customizing with CSS

The default transition is a cross-fade. Customize it using the ::view-transition-old and ::view-transition-new pseudo-elements:

css
/* Faster transition */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.2s;
}

/* Slide instead of fade */
::view-transition-old(root) {
  animation: slide-out 0.3s ease-in;
}
::view-transition-new(root) {
  animation: slide-in 0.3s ease-out;
}

Assign view-transition-name to elements that should animate independently (e.g., a hero image that morphs between pages):

css
.hero-image {
  view-transition-name: hero;
}

TIP

View transitions are progressive enhancement. Browsers that do not support the API fall back to instant navigation with no errors.