Svelte入門:リファレンス @sveltejs/kit -Vol.14-

スポンサーリンク
Svelte入門:リファレンス @sveltejs/kit -Vol.14- 用語解説
Svelte入門:リファレンス @sveltejs/kit -Vol.14-
この記事は約9分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、SvelteKitのリファレンスについて解説しています。

スポンサーリンク

背景

SvelteKitのリファレンスについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。

@sveltejs/kit

Reroute

バージョン2.3.0から利用可能

rerouteフックを使用すると、どのルートをレンダリングするかを決定する前にURLを修正することができます。

type Reroute = (event: { url: URL }) => void | string;

このフックは、URLベースのルーティングロジックをカスタマイズする必要がある場合に特に有用です。例えば:

  • URLの正規化
  • 古いURLパターンのリダイレクト
  • A/Bテスト用のURLの振り分け
  • カスタムURLルーティングルールの実装

戻り値がvoidの場合はURLの変更なし、stringを返す場合は新しいURLパスとして使用されます。

解説

rerouteフックについて詳しく解説させていただきます。

1. 基本的な機能

rerouteフックは、SvelteKitアプリケーションでURLの処理を行う最も早い段階で実行されるフックです。実際のルーティング処理が行われる前に、URLを変更または調整する機会を提供します。

2. 主な使用例
URLの正規化
export const reroute = ({ url }) => {
  // 末尾のスラッシュを統一的に削除
  if (url.pathname.endsWith('/') && url.pathname !== '/') {
    return url.pathname.slice(0, -1);
  }
}
レガシーURLのリダイレクト
export const reroute = ({ url }) => {
  // 古いURLパターンを新しいパターンに変換
  if (url.pathname.startsWith('/old-blog/')) {
    return url.pathname.replace('/old-blog/', '/blog/');
  }
}
A/Bテスト
export const reroute = ({ url }) => {
  // ユーザーをランダムに異なるバージョンに振り分け
  if (url.pathname === '/landing') {
    return Math.random() < 0.5 ? '/landing-a' : '/landing-b';
  }
}
3. 重要なポイント
  1. 実行タイミング
  • ルーティング処理の最初の段階で実行される
  • その他のフック(handle, handleError等)より先に実行される
  1. 戻り値
  • void: URLを変更しない
  • string: 新しいURLパスとして使用される
  1. 制限事項
  • クエリパラメータやハッシュの変更には直接影響しない
  • パスの変更のみが可能
4. ベストプラクティス
  1. シンプルに保つ
   export const reroute = ({ url }) => {
     // 複雑なロジックは避け、シンプルな変換に留める
     if (url.pathname === '/home') {
       return '/';
     }
   }
  1. パフォーマンスへの配慮
   export const reroute = ({ url }) => {
     // 重い処理は避ける
     // 単純なパターンマッチングや文字列置換に留める
   }
5. 応用例
国際化対応
export const reroute = ({ url }) => {
  // URLの先頭に言語コードがない場合、デフォルト言語を追加
  if (!url.pathname.match(/^\/[a-z]{2}\//)) {
    return `/en${url.pathname}`;
  }
}

このフックは、アプリケーションのルーティングロジックをカスタマイズする強力なツールですが、複雑な処理は避け、必要最小限の変換に留めることが推奨されます。

ResolveOptions

interface ResolveOptions {…}
transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise<string | undefined>;
  • input HTMLチャンクと、これが最後のチャンクかどうかの情報

HTMLにカスタム変換を適用します。donetrueの場合、それは最終チャンクです。チャンクは必ずしも整形されたHTML(例えば、要素の開始タグはあるが閉じタグがないなど)である保証はありませんが、%sveltekit.head%やレイアウト/ページコンポーネントなどの適切な境界で常に分割されます。

filterSerializedResponseHeaders?: (name: string, value: string) => boolean;
  • name ヘッダー名
  • value ヘッダー値

load関数がfetchでリソースを読み込む際に、シリアライズされたレスポンスにどのヘッダーを含めるかを決定します。デフォルトでは、ヘッダーは一切含まれません。

preload?: (input: { type: 'font' | 'css' | 'js' | 'asset'; path: string }) => boolean;
  • input ファイルの種類とそのパス

<head>タグに何を追加してプリロードするかを決定します。デフォルトでは、jscssファイルがプリロードされます。

解説

1. ページチャンクの変換(transformPageChunk)

このオプションは、HTMLの生成プロセスをカスタマイズするための強力な機能を提供します。

const options: ResolveOptions = {
  transformPageChunk: ({ html, done }) => {
    // Google Analyticsを追加する例
    if (done) {
      return html + `
        <script>
          // Google Analytics コード
        </script>
      `;
    }
    return html;
  }
};
重要な特徴:
  • チャンク単位での処理が可能
  • 最終チャンク(done: true)で全体の処理を完了
  • HTML変換やスクリプト挿入などのカスタマイズが可能
2. レスポンスヘッダーのフィルタリング(filterSerializedResponseHeaders)

fetchリクエストのレスポンスヘッダーの取り扱いを制御します。

const options: ResolveOptions = {
  filterSerializedResponseHeaders: (name, value) => {
    // キャッシュ関連のヘッダーのみを許可
    return name.toLowerCase().startsWith('cache-');
  }
};
主な用途:
  • セキュリティ関連ヘッダーの制御
  • キャッシュ制御
  • パフォーマンス最適化
3. プリロード制御(preload)

リソースのプリロード動作をカスタマイズできます。

const options: ResolveOptions = {
  preload: ({ type, path }) => {
    // フォントとCSSのみプリロード
    return type === 'font' || type === 'css';
  }
};
サポートされるタイプ:
  • font: フォントファイル
  • css: スタイルシート
  • js: JavaScriptファイル
  • asset: その他のアセット
使用例:
  1. 選択的プリロード
preload: ({ type, path }) => {
  // 特定のパスのリソースのみプリロード
  return path.includes('/critical/');
}
  1. タイプベースのフィルタリング
preload: ({ type }) => {
  // JavaScriptファイルのプリロードを無効化
  return type !== 'js';
}
実践的な使用例
1. 開発環境特有の変換
const options: ResolveOptions = {
  transformPageChunk: ({ html, done }) => {
    if (process.env.NODE_ENV === 'development') {
      return html + '<!-- 開発環境用デバッグ情報 -->';
    }
    return html;
  }
};
2. セキュリティヘッダーの制御
const options: ResolveOptions = {
  filterSerializedResponseHeaders: (name) => {
    // セキュリティ関連のヘッダーのみを許可
    const allowedHeaders = ['content-security-policy', 'x-frame-options'];
    return allowedHeaders.includes(name.toLowerCase());
  }
};
3. パフォーマンス最適化
const options: ResolveOptions = {
  preload: ({ type, path }) => {
    // 重要なリソースのみを事前読み込み
    return type === 'css' || (type === 'js' && path.includes('critical'));
  }
};

これらのオプションを適切に組み合わせることで、アプリケーションのパフォーマンス、セキュリティ、カスタマイズ性を向上させることができます。

おわりに

今日は、 SvelteKitのリファレンスについて解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました