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 に最適。