View Transitions による SPA ページナビゲーション

React・Vue・Svelte アプリケーションで、ルーターの setState 呼び出しを document.startViewTransition() でラップするだけでルート切替をアニメーション化。

UI Patterns

詳細な説明

普遍的な SPA パターン

すべての SPA フレームワークは突き詰めれば「ステート設定 → 再描画 → DOM 更新」です。最後の操作をラップしましょう:

// React Router 6.4+
import { unstable_useViewTransitionState } from 'react-router-dom';

function MyLink({ to, children }) {
  return <Link to={to} viewTransition>{children}</Link>;
}
// 手動/Next.js App Router
function navigate(href) {
  if (!document.startViewTransition) {
    router.push(href);
    return;
  }
  document.startViewTransition(() => {
    flushSync(() => router.push(href));
  });
}

flushSync が重要です。React はデフォルトでステート更新をバッチ処理しますが、View Transitions API はコールバック内で 同期的に DOM が変更されている必要があります。そうしないと2枚目のスナップショットを正しいタイミングで取れません。

デフォルトのクロスフェードで十分

ほとんどのルートトランジションでは、デフォルトのクロスフェードが見栄えします。カスタム CSS が必要なのは、方向性スライド(戻る vs 進む)や共通要素モーフ(カード内の hero イメージ)の場合だけです。

ルートごとのカスタマイズ

現在のルートに基づいて <html> に CSS クラスを追加し、トランジション CSS をスコープします:

.route-product-detail ::view-transition-new(root) {
  animation: 400ms ease-out both slide-up;
}

各ルートのトランジションが分離され、アニメーションルールのカスケードが防がれます。

クロスドキュメント代替(MPA)

JavaScript ルーターを持たないマルチページアプリケーションでは、両ページの CSS に追加します:

@view-transition {
  navigation: auto;
}

ブラウザが同一オリジンのナビゲーションを自動的に処理します。

ユースケース

React Router、TanStack Router、Vue Router、SvelteKit、Next.js App Router アプリケーション全般。Framer Motion や React Spring をバンドルせずにネイティブアプリ品質のナビゲーションを得たい SPA に最適。

試してみるView Transitions API ジェネレーター

フルツールを開く