Skip to content

Page Transition Wrapper

A dependency-free route transition shell with fade-through, shared-axis slide, scale and clip-reveal wipe modes. Direction-aware, interruption-safe, with focus moved to the new heading and a live route announcement.

DOM + CSS0 deps1 file · 10 KB TSXreduced-motion aware

Prominimaleditorial
Preview

Props

0.35

The source is part of Pro

$27/month or $179 once. See Pro

No runtime dependencies
"use client";

import {
  useCallback,
  useEffect,
  useRef,
  useState,
  useSyncExternalStore,
  type CSSProperties,
  type ReactNode,
} from "react";

/*
 * PageTransitionWrapper: a dependency-free route transition shell.
 *
 * Give it a stable, unique `transitionKey` (the route pathname). Without one,
 * unrelated pages are treated as the same page and the transition is skipped.
 *

  // ---------------------------------------------------------------
  // Full source available with a viberdy Pro subscription.
  // https://viberdy.dev/pricing
  // ---------------------------------------------------------------
}
Details

About this animation

Page Transition Wrapper is a route transition shell in plain React and CSS, no animation library. Give it a stable transitionKey (the pathname) and it keeps the outgoing page mounted in its own stacked layer while the new one enters. Four modes: fade (fade-through, the old page fades and scales down, then the new one arrives), slide (shared axis, both pages travel 40px along x), scale, and wipe (clip-reveal, the new page is uncovered by an animated clip-path edge while the old one recedes underneath). It is direction-aware: with direction auto, returning to the previous key plays in reverse (the slide flips sides, the wipe opens from the left); pass forward or back yourself when your router knows better. It is interruption-safe: layers are never recreated mid-flight, so clicking again simply retargets the running CSS transitions from wherever they are, and navigating back to a page that is still leaving revives that same layer. Only opacity, transform and clip-path animate. Notes: wipe reveals one page over another, so give the wrapper an opaque background (layers inherit it); layers sit in a one-cell grid so the wrapper is as tall as the tallest page; and the transitionKey must change for the route, not for every render.

Curator’s note

Rebuilt in October without framer-motion: the old fade, slide and scale props still work, and there is now a clip-reveal wipe, back-aware direction and focus management.

Pairs well with

Pro
Pro