よっしー
こんにちは。よっしーです(^^)
今日は、SvelteKitでのShallow routingについて解説しています。
背景
SvelteKitでのShallow routingについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
ルートのデータ読み込み
シャロールーティングを行う場合、現在のページ内で別の+page.svelte
をレンダリングしたい場合があります。例えば、写真のサムネイルをクリックすると、写真ページに移動せずに詳細ビューをポップアップ表示するような場合です。
これを実現するには、その+page.svelte
が期待するデータを読み込む必要があります。便利な方法として、<a>
要素のclick
ハンドラ内でpreloadData
を使用する方法があります。要素(または親要素)がdata-sveltekit-preload-data
を使用している場合、データは既にリクエストされており、preloadData
はそのリクエストを再利用します。
<script>
import { preloadData, pushState, goto } from '$app/navigation';
import { page } from '$app/stores';
import Modal from './Modal.svelte';
import PhotoPage from './[id]/+page.svelte';
let { data } = $props();
</script>
{#each data.thumbnails as thumbnail}
href="/photos/{thumbnail.id}"
on:click={async (e) => {
if (innerWidth < 640 // 画面が小さすぎる場合は中止
|| e.shiftKey // または新しいウィンドウで開く場合
|| e.metaKey || e.ctrlKey // または新しいタブで開く場合(Mac: metaKey, Win/Linux: ctrlKey)
// マウスのスクロールホイールでのクリックも考慮すべき
) return;
// 通常のナビゲーションを防止
e.preventDefault();
const { href } = e.currentTarget;
// `load`関数を実行(より正確には、`data-sveltekit-preload-data`により
// 既に実行中の`load`関数の結果を取得)
const result = await preloadData(href);
if (result.type === 'loaded' && result.status === 200) {
pushState(href, { selected: result.data });
} else {
// 何か問題が発生した場合は通常のナビゲーションを試行
goto(href);
}
}}
>
<img alt={thumbnail.alt} src={thumbnail.src} />
</a>
{/each}
{#if $page.state.selected}
<Modal on:close={() => history.back()}>
<!-- SvelteKitがナビゲーション時に行うのと同じように、
ページデータを+page.svelteコンポーネントに渡す -->
<PhotoPage data={$page.state.selected} />
</Modal>
{/if}
解説
このコードは、高度なユーザーインターフェースパターンを実装する方法を示しています。主なポイントは:
- シャロールーティング:
- ページ全体を再読み込みせずにコンテンツを更新
- モーダル表示による詳細ビューの実装
- ユーザー体験の向上
- データのプリロード:
preloadData
関数の使用data-sveltekit-preload-data
による最適化- リクエストの再利用
- 条件分岐:
- 画面サイズによる分岐
- 特殊キー(Shift、Ctrl、Meta)の処理
- エラー時のフォールバック
- 状態管理:
pushState
による履歴エントリの作成- モーダル表示の制御
- データの受け渡し
- アクセシビリティとUX:
- 適切なフォールバック
- エラーハンドリング
- 様々なユースケースへの対応
このパターンは以下のような場合に特に有用です:
- ギャラリーやポートフォリオサイト
- 詳細ビューが必要なリスト表示
- インタラクティブなコンテンツブラウジング
おわりに
今日は、 SvelteKitでのShallow routingについて解説しました。
よっしー
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント