メインコンテンツへスキップ
#Web制作 約9分で読めます

Astro 5.0 View Transitions で SPAライクなMPA を実装する【2026年5月最新】

Astro 5.0の View Transitions API を活用し、MPA の SEO メリットを保ちながら SPA 風のスムーズな画面遷移を実装する方法を解説します

Astro View Transitions がもたらす MPA の新しい可能性

従来、MPA(Multi-Page Application)は SEO に強い反面、ページ遷移時に画面全体が再読み込みされるため、ユーザー体験が SPA(Single-Page Application)に劣るとされてきました。

しかし Astro 5.0(2025年12月リリース) では、View Transitions API のサポートが大幅に強化され、MPA でありながら SPA のようなスムーズな画面遷移を実現できるようになりました。この記事では、Astro 5.0 における View Transitions の実装方法と、実プロジェクトで活用する際のベストプラクティスを解説します。

この記事で解決できること

  • Astro 5.0 で View Transitions を有効化する基本設定
  • ページ間遷移時のアニメーション制御
  • 共通要素(ヘッダー・画像など)の遷移維持
  • パフォーマンスとアクセシビリティの両立
  • フォールバック戦略とブラウザ対応

Astro 5.0 View Transitions の基本実装

Astro 5.0 では、<ViewTransitions /> コンポーネントを使用することで、ページ遷移時に自動的にスムーズなアニメーションが適用されます。

基本セットアップ

まず、レイアウトファイルに ViewTransitions コンポーネントを追加します。

---
// src/layouts/BaseLayout.astro
import { ViewTransitions } from 'astro:transitions';
---
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{Astro.props.title}</title>
  <ViewTransitions />
</head>
<body>
  <slot />
</body>
</html>

これだけで、ページ間のナビゲーション時にデフォルトのフェードアニメーションが適用されます。

View Transitions の動作フロー

sequenceDiagram
    participant User as ユーザー
    participant Browser as ブラウザ
    participant Astro as Astro Router
    participant API as View Transitions API

    User->>Browser: リンククリック
    Browser->>Astro: ナビゲーションイベント
    Astro->>API: document.startViewTransition()
    API->>Browser: 現在のページをキャプチャ
    Astro->>Astro: 新しいページの HTML を fetch
    Astro->>Browser: DOM を更新
    API->>Browser: トランジションアニメーション実行
    Browser->>User: スムーズな画面遷移

上記のシーケンス図は、Astro が内部的に View Transitions API を呼び出し、DOM の更新とアニメーションを制御する流れを示しています。従来の MPA では「リンククリック → 画面全体のリロード」という単純なフローでしたが、Astro では JavaScript によるクライアントサイドルーティングに切り替わります。

共通要素の遷移維持:transition:persist と transition:name

View Transitions の強力な機能の一つが、ページ間で共通の要素を維持し、アニメーションさせることです。

transition:persist による状態維持

transition:persist ディレクティブを使用すると、要素の状態(再生中の動画、フォーム入力、スクロール位置など)がページ遷移後も保持されます。

---
// src/components/MusicPlayer.astro
---
<div transition:persist="music-player">
  <audio controls>
    <source src="/music/bgm.mp3" type="audio/mpeg">
  </audio>
</div>

この例では、ページ遷移しても音楽プレイヤーの再生状態が維持されます。transition:persist="music-player" の値は、ページ間で要素を一意に識別するための ID です。

transition:name によるモーフィングアニメーション

transition:name を使うと、ページ間で同じ名前を持つ要素が自動的にモーフィング(形状変化)アニメーションします。

---
// src/pages/blog/[slug].astro
const { slug } = Astro.params;
const post = await getPost(slug);
---
<article>
  <img 
    src={post.image} 
    alt={post.title}
    transition:name={`post-image-${slug}`}
    class="w-full h-64 object-cover"
  />
  <h1>{post.title}</h1>
  <div set:html={post.content} />
</article>

一覧ページ側でも同じ transition:name を指定します。

---
// src/pages/blog/index.astro
const posts = await getPosts();
---
<div class="grid grid-cols-3 gap-4">
  {posts.map(post => (
    <a href={`/blog/${post.slug}`}>
      <img 
        src={post.image} 
        alt={post.title}
        transition:name={`post-image-${post.slug}`}
        class="w-full h-48 object-cover"
      />
      <h2>{post.title}</h2>
    </a>
  ))}
</div>

これにより、一覧ページのサムネイルをクリックすると、画像が滑らかに拡大しながら詳細ページに遷移します。

カスタムアニメーションの実装

デフォルトのフェードアニメーションではなく、独自のアニメーションを定義することも可能です。

CSS によるカスタムトランジション

---
// src/layouts/BaseLayout.astro
import { ViewTransitions } from 'astro:transitions';
---
<html lang="ja">
<head>
  <ViewTransitions />
  <style is:global>
    /* 新しいページがスライドインする */
    ::view-transition-new(root) {
      animation: slide-in 0.3s ease-out;
    }

    /* 古いページがスライドアウトする */
    ::view-transition-old(root) {
      animation: slide-out 0.3s ease-out;
    }

    @keyframes slide-in {
      from {
        transform: translateX(100%);
      }
      to {
        transform: translateX(0);
      }
    }

    @keyframes slide-out {
      from {
        transform: translateX(0);
      }
      to {
        transform: translateX(-100%);
      }
    }
  </style>
</head>
<body>
  <slot />
</body>
</html>

JavaScript によるプログラマティック制御

Astro 5.0 では、astro:before-preparationastro:after-swap などのライフサイクルイベントをフックできます。

---
// src/layouts/BaseLayout.astro
---
<script>
  document.addEventListener('astro:before-preparation', (event) => {
    console.log('ページ遷移準備中:', event.to.pathname);
    
    // ローディングインジケーターを表示
    document.body.classList.add('is-loading');
  });

  document.addEventListener('astro:after-swap', () => {
    console.log('DOM 更新完了');
    
    // ローディングインジケーターを非表示
    document.body.classList.remove('is-loading');
    
    // Google Analytics などのトラッキングコードを再実行
    if (typeof gtag !== 'undefined') {
      gtag('config', 'GA_MEASUREMENT_ID', {
        page_path: window.location.pathname,
      });
    }
  });
</script>

パフォーマンスとアクセシビリティの考慮

View Transitions を使用する際は、パフォーマンスとアクセシビリティのバランスを取ることが重要です。

プリフェッチによる高速化

Astro 5.0 では、data-astro-prefetch 属性を使ってページを事前読み込みできます。

<nav>
  <a href="/" data-astro-prefetch>ホーム</a>
  <a href="/about" data-astro-prefetch>会社概要</a>
  <a href="/blog" data-astro-prefetch>ブログ</a>
</nav>

プリフェッチ戦略は3種類あります。

戦略説明使い所
hoverリンクにホバーした時に読み込みデフォルト・デスクトップ向け
tapリンクをタップした時に読み込みモバイル向け
viewportリンクが画面内に入った時に読み込みファーストビューの次のコンテンツ

設定ファイルでデフォルト戦略を変更できます。

// astro.config.mjs
export default {
  prefetch: {
    defaultStrategy: 'viewport',
    prefetchAll: true
  }
}

アクセシビリティ対応

View Transitions は視覚的なアニメーションを伴うため、motion sensitivity(動きに敏感なユーザー)への配慮が必要です。

/* prefers-reduced-motion が有効な場合はアニメーションを無効化 */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-new(root),
  ::view-transition-old(root) {
    animation: none;
  }
}

また、スクリーンリーダー使用者のために、aria-live 領域でページ遷移を通知することも推奨されます。

<div aria-live="polite" aria-atomic="true" class="sr-only">
  <span id="page-title-announce"></span>
</div>

<script>
  document.addEventListener('astro:after-swap', () => {
    const titleElement = document.getElementById('page-title-announce');
    if (titleElement) {
      titleElement.textContent = `${document.title} に移動しました`;
    }
  });
</script>

フォールバック戦略とブラウザ対応

View Transitions API は比較的新しい API のため、ブラウザ対応状況を確認する必要があります。

2026年5月時点のブラウザ対応状況

ブラウザバージョン対応状況
Chrome / Edge111+完全対応
Safari17.4+完全対応(iOS 17.4+)
Firefox126+実験的サポート(about:config で有効化)

Astro は View Transitions API が非対応のブラウザでは、自動的に通常の MPA ナビゲーションにフォールバックします。追加のコードは不要です。

フォールバック時の動作確認

開発者ツールで View Transitions を無効化して、フォールバック時の動作を確認できます。

// ブラウザコンソールで実行
document.startViewTransition = undefined;

実プロジェクトでの活用事例

ブログサイトでの実装例

記事一覧から詳細ページへの遷移で、サムネイル画像を維持しながらスムーズに拡大する実装です。

---
// src/pages/blog/index.astro
const posts = await getPosts();
---
<BaseLayout>
  <h1>ブログ記事一覧</h1>
  <div class="grid grid-cols-3 gap-6">
    {posts.map(post => (
      <article>
        <a href={`/blog/${post.slug}`} data-astro-prefetch="viewport">
          <img 
            src={post.thumbnail} 
            alt={post.title}
            transition:name={`hero-${post.slug}`}
            class="rounded-lg shadow-md"
          />
          <h2 class="mt-4 text-xl font-bold">{post.title}</h2>
          <p class="text-gray-600">{post.excerpt}</p>
        </a>
      </article>
    ))}
  </div>
</BaseLayout>

詳細ページ側でも同じ transition:name を指定することで、画像がモーフィングします。

---
// src/pages/blog/[slug].astro
const { slug } = Astro.params;
const post = await getPost(slug);
---
<BaseLayout>
  <article>
    <img 
      src={post.thumbnail} 
      alt={post.title}
      transition:name={`hero-${slug}`}
      class="w-full h-96 object-cover rounded-lg"
    />
    <h1 class="text-4xl font-bold mt-8">{post.title}</h1>
    <div class="prose prose-lg mt-6" set:html={post.content} />
  </article>
</BaseLayout>

EC サイトでの実装例

商品一覧から商品詳細への遷移で、商品画像とカート状態を維持します。

---
// src/components/Cart.astro
---
<div 
  transition:persist="shopping-cart"
  class="fixed top-4 right-4 bg-white p-4 rounded shadow"
>
  <span id="cart-count">0</span> 点
</div>

カートアイコンは transition:persist により、ページ遷移後も状態が保持されます。

まとめ

Astro 5.0 の View Transitions を活用することで、以下のメリットが得られます。

  • MPA の SEO メリットを保ちながら SPA 風の UX を実現
  • 共通要素の状態維持により、音楽プレイヤーやカートなどが途切れない
  • transition:name によるモーフィングアニメーションで自然な画面遷移
  • プリフェッチによる体感速度の向上
  • アクセシビリティへの配慮が標準で組み込まれている

View Transitions は、現代の Web サイトにおいて「SEO」と「UX」のトレードオフを解消する強力な技術です。Astro 5.0 では、この API を非常にシンプルに扱えるため、プロダクションでの採用ハードルが大きく下がりました。

今後、View Transitions API のブラウザ対応が進むにつれ、MPA の標準的な実装パターンとして定着していくでしょう。

参考リンク

#Astro #View Transitions #MPA #パフォーマンス最適化 #UX
シェア