こんにちは😊
株式会社プロドウガの@YushiYamamotoです!
らくらくサイトの開発・運営を担当しながら、React.js・Next.js専門のフリーランスエンジニアとしても活動しています❗️
昨日は「Islands Architecture」でJavaScriptを極限まで減らす話(引き算の美学)をしました。
今日は逆に、**「MPA(マルチページアプリケーション)なのに、まるでネイティブアプリのようなリッチな遷移アニメーション」**を実現する、Astroの魔法のような機能についてお話しします。
Astro 5.0で正式にリネームされた <ClientRouter />(旧 <ViewTransitions />)を使えば、あなたのサイトは「ただの静的サイト」から「体験型Webアプリケーション」へと進化します。
1. なぜ「画面遷移」が重要なのか? 🤔
従来のWebサイト(MPA)では、リンクをクリックするたびに画面が白くなり、CSSやJSが再読み込みされ、スクロール位置がリセットされていました。
これはユーザーにとって**「待たされている感」**を強く与える要因です。
一方、SPA(Next.jsなど)は遷移が滑らかですが、構築コストやバンドルサイズが大きくなりがちです。
Astroの <ClientRouter /> は、この「いいとこ取り」をします。
HTMLベースの軽量さを保ちつつ、ブラウザ標準の View Transitions API をラップして、SPAのようなシームレスな遷移を提供します。
2. 30秒で導入!魔法のコンポーネント 🪄
導入は驚くほど簡単です。共通レイアウトの <head> にコンポーネントを置くだけ。
※ Astro 5.0以降は <ViewTransitions /> ではなく <ClientRouter /> を使用します。
layouts/Layout.astro
---
import { ClientRouter } from 'astro:transitions';
---
<html lang="ja">
<head>
<title>My Awesome Site</title>
<!-- 👇 これを追加するだけ! -->
<ClientRouter />
</head>
<body>
<slot />
</body>
</html>
たったこれだけで、サイト内の全リンクがフェードイン・フェードアウトのアニメーションに変わります。
ブラウザの「戻る」「進む」ボタンを押しても、再読み込みなしでスッと画面が切り替わります。
3. 実践テクニック①:要素が変形して移動する (Morphing) 🦋
「一覧ページの商品画像」が、「詳細ページのメイン画像」に拡大しながら移動するエフェクト。
AppleのApp Storeなどでよく見るアレです。
Astroなら、同じ名前 (transition:name) を付けるだけで自動的に補完してくれます。
一覧ページ (pages/index.astro)
---
const products = [
{ id: '1', title: 'すごいカメラ', img: '/camera.jpg' },
// ...
];
---
{products.map((product) => (
<a href={`/products/${product.id}`}>
<img
src={product.img}
/* 👇 ここにユニークな名前をつける */
transition:name={`hero-${product.id}`}
class="w-32 h-32 object-cover"
/>
<p>{product.title}</p>
</a>
))}
詳細ページ (pages/products/[id].astro)
---
const { id } = Astro.params;
---
<div class="p-10">
<img
src={`/camera.jpg`}
/* 👇 同じ名前をつけるだけで、Astroが自動でモーフィング! */
transition:name={`hero-${id}`}
class="w-full h-96 object-cover"
/>
</div>
これだけで、画像が「フワッ」と拡大して詳細ページに収まるアニメーションが完成します。JSは1行も書いていません。
4. 実践テクニック②:状態を維持する (Persist) 📺
MPAの弱点は「ページ遷移で状態がリセットされる」ことですが、transition:persist を使えば解決です。
例えば、**「ページを移動しても再生し続ける音楽プレーヤー」や「スクロール位置を保持したままのサイドバー」**が作れます。
<!-- components/AudioPlayer.astro -->
<div transition:persist class="fixed bottom-0 w-full bg-gray-900 p-4">
<audio controls>
<source src="/music.mp3" type="audio/mpeg">
</audio>
<p class="text-white">ページ遷移しても音楽は止まりません🎵</p>
</div>
このコンポーネントをLayoutに置いておけば、ユーザーがどのページに飛んでも音楽は途切れません。
これは従来のMPAでは絶対に不可能だった体験です。
5. ハマりどころ:スクリプトが動かない!? 😱
<ClientRouter /> を使うと、ページ遷移は「擬似的なSPA遷移(Soft Navigation)」になります。
そのため、window.onload や DOMContentLoaded は最初の1回しか発火しません。
ハンバーガーメニューやスライダーなどのJSが「2ページ目以降で動かない」という現象が起きます。
解決策:astro:page-load イベントを使う
Astroは専用のライフサイクルイベントを用意しています。
<script>
// ❌ これは最初のページロード時しか動かない
// document.addEventListener('DOMContentLoaded', () => { ... });
// ✅ これならページ遷移のたびに毎回動く!
document.addEventListener('astro:page-load', () => {
console.log('新しいページがレンダリングされました✨');
initMenu(); // メニューの初期化など
});
</script>
サードパーティスクリプトの注意点
Google Analyticsや広告タグなどは、ページ遷移時に手動でPVイベントを送る必要がある場合があります。Astro公式のインテグレーションを使っている場合は自動対応されていることが多いですが、自前で入れている場合は要注意です。
6. まとめ:Astroは「静的サイト」の枠を超えた 🚀
Astro 5.0の <ClientRouter /> は、**「開発者はMPAのようにシンプルに作り、ユーザーにはSPAのようにリッチに届ける」**ことを可能にしました。
- 導入は
<ClientRouter />を置くだけ。 transition:nameで要素をつなぐ。transition:persistで状態を維持する。astro:page-loadでスクリプトを再実行する。
これらを使いこなせば、Next.jsで作るようなリッチなメディアサイトを、圧倒的に軽いJSサイズで実現できます。
明日は、さらに踏み込んで**「Astro DB / Server Actions を使った動的アプリケーション開発」**について解説します。
「AstroってDBも扱えるの!?」という驚きをお届けします。お楽しみに!👋
最後に:業務委託のご相談を承ります
私は業務委託エンジニアとしてWEB制作やシステム開発を請け負っています。最新技術を活用したレスポンシブなWebサイト制作、インタラクティブなアプリケーション開発、API連携など幅広いご要望に対応可能です。
「課題解決に向けた即戦力が欲しい」「高品質なWeb制作を依頼したい」という方は、お気軽にご相談ください。一緒にビジネスの成長を目指しましょう!
👉 ポートフォリオ
🌳 らくらくサイト