こんにちは。よっしーです(^^)
今日は、SvelteKitでのページオプションについて解説しています。
背景
SvelteKitでのページオプションについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
SvelteKitでのページオプションについて
SvelteKitは基本的に、コンポーネントをまずサーバー上でレンダリング(またはプリレンダリング)し、HTMLとしてクライアントに送信します。その後、ブラウザ上で再度レンダリングして、「ハイドレーション」と呼ばれるプロセスで対話性を持たせます。そのため、コンポーネントが両方の環境で動作することを確認する必要があります。その後、SvelteKitは後続のナビゲーションを制御する「ルーター」を初期化します。
これらの動作は、+page.js
や+page.server.js
からオプションをエクスポートすることで、ページごとに制御できます。また、共有の+layout.js
や+layout.server.js
を使用して、ページのグループに対して制御することもできます。アプリ全体に対するオプションを定義するには、ルートレイアウトからエクスポートします。
これらのオプションをアプリの異なる領域で組み合わせることができます。例えば、マーケティングページをプリレンダリングして最高速度を実現し、動的ページをサーバーレンダリングしてSEOとアクセシビリティを確保し、管理セクションをクライアントのみでレンダリングしてSPAにすることができます。これにより、SvelteKitは非常に多用途になります。
サーバーでの事前レンダリング
prerender
オプションの特殊性:- 他のページオプションとは異なり、
prerender
は+server.js
ファイルにも適用されます。
- 他のページオプションとは異なり、
+server.js
ファイルの特徴:- これらのファイルはレイアウトの影響を受けません。
- しかし、これらのファイルからデータをフェッチするページがある場合、そのページのデフォルト値を継承します。
- 例示:
- 文章では、
+page.js
内のload
関数の例を示そうとしています。このload
関数が+server.js
ファイルのプリレンダリング動作に影響を与える可能性があることを示唆しています。
- 文章では、
この説明は、SvelteKitのプリレンダリング機能が+server.js
ファイルに対してどのように働くかを理解する上で重要です。特に、ページとサーバーファイルの間でのプリレンダリング設定の継承関係を示しています。
// +page.js
export const prerender = true;
/** @type {import('./$types').PageLoad} */
export async function load({ fetch }) {
const res = await fetch('/my-server-route.json');
return await res.json();
}
src/routes/my-server-route.json/+server.js は、独自のエクスポート const prerender = false が含まれていない場合、事前レンダリング可能として扱われます。
プリレンダリングしない場合
基本的なルールは次のとおりです。ページを事前レンダリング可能にするには、そのページに直接アクセスする 2 人のユーザーがサーバーから同じコンテンツを取得する必要があります。
プリレンダリングを使用する際の注意点
- プリレンダリングの適合性:
- すべてのページがプリレンダリングに適しているわけではありません。
- プリレンダリングの特徴:
- プリレンダリングされたコンテンツは、すべてのユーザーに同じ内容が表示されます。
- パーソナライズされたデータの取り扱い:
- プリレンダリングされたページでも、
onMount
内でパーソナライズされたデータをフェッチすることは可能です。
- プリレンダリングされたページでも、
- ユーザー体験への影響:
- しかし、この方法は以下の理由でユーザー体験を低下させる可能性があります:
- 初期コンテンツが空白になる
- ローディングインジケータが表示される
- しかし、この方法は以下の理由でユーザー体験を低下させる可能性があります:
開発者は、コンテンツの性質とユーザー体験のバランスを考慮して、プリレンダリングの適用を決定する必要があります。
プリレンダリング機能の柔軟性と制限事項
- パラメータに基づくデータロード:
- ページのパラメータに基づいてデータをロードするページ(例:
src/routes/blog/[slug]/+page.svelte
)も、プリレンダリングが可能です。
- ページのパラメータに基づいてデータをロードするページ(例:
url.searchParams
の使用制限:- プリレンダリング中に
url.searchParams
にアクセスすることは禁止されています。 - 必要な場合は、ブラウザ内でのみ使用するようにしてください(例:
onMount
内で使用)。
- プリレンダリング中に
- アクションを持つページの制限:
- アクション(actions)を持つページはプリレンダリングできません。
- 理由:サーバーがアクションの
POST
リクエストを処理できる必要があるため。
開発者は、動的ルートのプリレンダリング、クエリパラメータの扱い、およびサーバーサイドのアクションとの相互作用について注意を払う必要があります。これらの点を考慮することで、効果的かつ適切にプリレンダリングを活用できます。
ルートの競合
- プリレンダリングの制約:
- プリレンダリングはファイルシステムに書き込むため、ディレクトリとファイルが同じ名前になるような2つのエンドポイントを持つことはできません。
- 例:
src/routes/foo/+server.js
とsrc/routes/foo/bar/+server.js
は、foo
とfoo/bar
を作成しようとしますが、これは不可能です。
- 推奨される解決策:
- 常にファイル拡張子を含めることが推奨されます。
- 例:
src/routes/foo.json/+server.js
とsrc/routes/foo/bar.json/+server.js
は、foo.json
とfoo/bar.json
というファイルを問題なく共存させることができます。
- ページに対する対処法:
- ページの場合、この問題を回避するために、
foo
の代わりにfoo/index.html
を作成します。
- ページの場合、この問題を回避するために、
開発者はこれらのガイドラインに従うことで、プリレンダリング時のファイル名の衝突を避け、効率的にアプリケーションを構築できます。
トラブルシューティング
- エラーメッセージ: ‘The following routes were marked as prerenderable, but were not prerendered’ (以下のルートはプリレンダリング可能とマークされていましたが、プリレンダリングされませんでした)
- エラーの原因:
- 問題のルート(またはページの場合は親レイアウト)で
export const prerender = true
が設定されている。 - しかし、そのページがプリレンダリングクローラーによって到達されなかった。
- 問題のルート(またはページの場合は親レイアウト)で
- 結果:
- 設定上はプリレンダリングされるはずのページが、実際にはプリレンダリングされていない状態になっている。
このエラーは、プリレンダリングの設定と実際のクローリング結果の不一致を示しています。開発者はこのメッセージを受け取った場合、以下の点を確認する必要があります:
- プリレンダリング設定が適切か
- クローラーがそのページに到達できない理由はないか(リンクの欠如など)
- 意図したとおりにページがプリレンダリングされているか
この情報は、SvelteKitアプリケーションの開発とデバッグ過程で重要な役割を果たします。
プリレンダリングされなかったルートは動的にサーバーレンダリングできないため、アクセス時にエラーが発生します。以下の方法で解決できます:
- SvelteKitがルートを見つけられるようにする:
config.kit.prerender.entries
またはentries
ページオプションからリンクをたどれるようにする。- 動的ルート(
[parameters]
を含むページ)へのリンクを、他のエントリーポイントからクロールしても見つからない場合、このオプションに追加する。 - プリレンダリング可能とマークされていないページは無視され、そのページからのリンクはクロールされません。
- サーバーサイドレンダリングが有効な他のプリレンダリングページからリンクを発見できるようにする。
- プリレンダリング設定を変更する:
export const prerender = true
をexport const prerender = 'auto'
に変更する。'auto'
に設定されたルートは動的にサーバーレンダリングできるようになります。
これらの解決策は、プリレンダリングプロセスを最適化し、意図したすべてのページが正しくプリレンダリングされるようにするための重要な方法です。開発者はこれらのアプローチを活用して、SvelteKitアプリケーションのパフォーマンスと安定性を向上させることができます。
おわりに
今日は、 SvelteKitでのページオプションについて解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント