SvelteKitプレースホルダー

SvelteKitのプレースホルダーは、HTMLテンプレート内で動的な値を埋め込むための特別な構文です。このページでは、すべてのプレースホルダーの詳細な仕様と使用方法を解説します。

プレースホルダーの仕組み

ダイアグラムを読み込み中...

プレースホルダーはビルド時またはレンダリング時にSvelteKitによって実際の値に置換されます。これらは文字列のテンプレートリテラルであり、JavaScriptコード内では使用できません。

全プレースホルダー一覧

📋 クイックナビゲーション

プレースホルダー名をクリックすると、詳細説明にジャンプします。

使用可能ファイルプレースホルダー用途参照元
app.html
%lang% HTML言語属性hooks.server.tsまたはデフォルト"en"
%sveltekit.assets% 静的アセットパスsvelte.config.jsのpaths.assets
%sveltekit.head% ページ固有のhead要素<svelte:head>やload関数
%sveltekit.body% アプリケーション本体ルート/ページコンポーネント
%sveltekit.nonce% CSP nonce値CSP設定から自動生成
%sveltekit.env.[NAME]% 公開環境変数PUBLIC_で始まる環境変数
error.html
%sveltekit.status% HTTPステータスエラーステータスコード
%sveltekit.error.message% エラーメッセージエラーオブジェクト

app.html用プレースホルダー

基本プレースホルダー

1. lang プレースホルダー

構文: %lang%
用途: HTML要素の言語属性を設定
参照元: hooks.server.tshandle関数で設定可能
デフォルト値: "en"

<!-- app.html -->
<!DOCTYPE html>
<html lang="%lang%">
html
// hooks.server.ts で言語を動的に設定
import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) => {
  // クッキーやヘッダーから言語を判定
  const lang = event.cookies.get('lang') || 
                event.request.headers.get('accept-language')?.split(',')[0] || 
                'ja';
  
  return await resolve(event, {
    transformPageChunk: ({ html }) => html.replace('%lang%', lang)
  });
};
typescript

2. sveltekit.assets プレースホルダー

構文: %sveltekit.assets%
用途: 静的アセットへのベースパス
参照元: svelte.config.jspaths.assets設定
デフォルト値: paths.baseへの相対パス

<!-- app.html -->
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
html
// svelte.config.js での設定
const config = {
  kit: {
    paths: {
      base: '/my-app',
      assets: 'https://cdn.example.com' // CDN使用時
    }
  }
};
javascript

3. sveltekit.head プレースホルダー

構文: %sveltekit.head%
用途: ページ固有のhead要素(meta、link、script等)
参照元:

  • 各ページの<svelte:head>ブロック
  • Load関数から返されるmetaタグ
  • SvelteKitが自動生成するプリロードヒント
<!-- app.html -->
<head>
  <meta charset="utf-8" />
  <link rel="icon" href="%sveltekit.assets%/favicon.png" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  %sveltekit.head%
</head>
html
<!-- +page.svelte -->
<svelte:head>
  <title>ページタイトル</title>
  <meta name="description" content="ページの説明" />
</svelte:head>
svelte

4. sveltekit.body プレースホルダー

構文: %sveltekit.body%
用途: レンダリングされたページのマークアップ
参照元: ルートとページコンポーネントの出力
注意: 直接<body>内ではなく、<div>等の要素内に配置

<!-- app.html -->
<body>
  <div style="display: contents">
    %sveltekit.body%
  </div>
</body>
html

セキュリティ関連プレースホルダー

5. sveltekit.nonce プレースホルダー

構文: %sveltekit.nonce%
用途: Content Security Policy (CSP)のnonce値
参照元: svelte.config.jsのCSP設定
使用場面: 手動で追加するインラインスクリプトやスタイル

<!-- app.html -->
<script nonce="%sveltekit.nonce%">
  // グローバル設定やポリフィルなど
  console.log('App initialized');
</script>

<style nonce="%sveltekit.nonce%">
  /* クリティカルCSS */
  body { margin: 0; }
</style>
html
// svelte.config.js でCSPを設定
const config = {
  kit: {
    csp: {
      mode: 'auto', // 'nonce' | 'hash' | 'auto'
      directives: {
        'script-src': ['self'],
        'style-src': ['self', 'unsafe-inline']
      }
    }
  }
};
javascript

環境変数プレースホルダー

6. sveltekit.env.[NAME] プレースホルダー

構文: %sveltekit.env.[NAME]%
用途: 公開環境変数の埋め込み
参照元: PUBLIC_プレフィックスを持つ環境変数
フォールバック: マッチしない場合は空文字列

<!-- app.html -->
<script nonce="%sveltekit.nonce%">
  window.API_URL = '%sveltekit.env.PUBLIC_API_URL%';
  window.APP_VERSION = '%sveltekit.env.PUBLIC_APP_VERSION%';
</script>
html
# .env ファイル
PUBLIC_API_URL=https://api.example.com
PUBLIC_APP_VERSION=1.0.0
PRIVATE_SECRET=secret123  # これは使用不可
bash

error.html用プレースホルダー

エラーページ専用のプレースホルダーです。アプリケーションが完全に失敗した場合に使用されます。

7. sveltekit.status プレースホルダー

構文: %sveltekit.status%
用途: HTTPステータスコード
参照元: エラーのステータスコード(404、500等)

8. sveltekit.error.message プレースホルダー

構文: %sveltekit.error.message%
用途: エラーメッセージ
参照元: エラーオブジェクトのメッセージ

<!-- error.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Error %sveltekit.status%</title>
</head>
<body>
  <h1>Error %sveltekit.status%</h1>
  <p>%sveltekit.error.message%</p>
</body>
</html>
html

プレースホルダー置換の流れ

ダイアグラムを読み込み中...

使用可能な場所と制限

使用可能な場所

ファイル使用可能なプレースホルダー
app.html%lang%, %sveltekit.assets%, %sveltekit.head%, %sveltekit.body%, %sveltekit.nonce%, %sveltekit.env.*%
error.html%sveltekit.status%, %sveltekit.error.message%

使用できない場所

  • JavaScriptファイル (+page.js, +server.js, hooks.server.js)
  • Svelteコンポーネント (+page.svelte, +layout.svelte)
  • TypeScriptファイル (.tsファイル全般)
  • Service Worker (service-worker.js)
  • その他の静的ファイル

代替アプローチ

プレースホルダーが使えない場所での代替方法

環境変数へのアクセス

// +page.server.ts で環境変数を使用
import { PUBLIC_API_URL } from '$env/static/public';
import { PRIVATE_API_KEY } from '$env/static/private';

export async function load() {
  const response = await fetch(PUBLIC_API_URL, {
    headers: {
      'Authorization': `Bearer ${PRIVATE_API_KEY}`
    }
  });
  
  return {
    data: await response.json()
  };
}
typescript

アセットパスへのアクセス

// +page.svelte でアセットパスを使用
import { base, assets } from '$app/paths';

const logoUrl = `${assets}/images/logo.png`;
typescript

CSP nonceの動的生成

// hooks.server.ts でカスタムCSP実装
import crypto from 'crypto';
import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) => {
  const nonce = crypto.randomBytes(16).toString('base64');
  
  const response = await resolve(event, {
    transformPageChunk: ({ html }) => {
      return html.replace(/%sveltekit\.nonce%/g, nonce);
    }
  });
  
  response.headers.set(
    'Content-Security-Policy',
    `script-src 'nonce-${nonce}' 'strict-dynamic';`
  );
  
  return response;
};
typescript

トラブルシューティング

よくある問題と解決策

1. プレースホルダーが置換されない

問題: %sveltekit.nonce%が文字列として表示される
原因: JavaScriptファイル内で使用している
解決: app.htmlでのみ使用する

// ❌ 間違い: +page.svelte内
const nonce = '%sveltekit.nonce%'; // 文字列として扱われる

// ✅ 正解: app.html内
<script nonce="%sveltekit.nonce%">
  // ここではnonceが適用される
</script>
javascript

2. 環境変数が空文字になる

問題: %sveltekit.env.MY_VAR%が空
原因: PUBLIC_プレフィックスがない
解決: 環境変数名をPUBLIC_MY_VARに変更

# 間違い
MY_VAR=value

# 正解
PUBLIC_MY_VAR=value
bash

3. エラーページが正しく表示されない

問題: error.htmlが機能しない
原因: プレースホルダーの誤字
解決: 正確な構文を使用

<!-- ❌ 間違い -->
%status% 
%message%

<!-- ✅ 正解 -->
%sveltekit.status%
%sveltekit.error.message%
html

ベストプラクティス

1. セキュリティを考慮した環境変数の使用

// svelte.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [sveltekit()],
  // 環境変数のプレフィックスを明示的に設定
  envPrefix: 'PUBLIC_'
});
typescript

2. CSPの適切な設定

// svelte.config.js
const config = {
  kit: {
    csp: {
      mode: 'auto',
      directives: {
        'default-src': ['self'],
        'script-src': ['self', 'https://trusted-cdn.com'],
        'style-src': ['self', 'unsafe-inline'], // 必要最小限に
        'img-src': ['self', 'data:', 'https:'],
        'font-src': ['self'],
        'connect-src': ['self', 'https://api.example.com']
      }
    }
  }
};
javascript

3. 多言語対応の実装

// hooks.server.ts
import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) => {
  // 言語判定ロジック
  const acceptLanguage = event.request.headers.get('accept-language');
  const cookieLang = event.cookies.get('preferred_language');
  
  const lang = cookieLang || 
               acceptLanguage?.split(',')[0].split('-')[0] || 
               'ja';
  
  // HTMLに言語を適用
  return await resolve(event, {
    transformPageChunk: ({ html }) => {
      return html.replace('%lang%', lang);
    }
  });
};
typescript

まとめ

SvelteKitのプレースホルダーは、HTMLテンプレートで動的な値を埋め込むための強力な機能です。ただし、使用できる場所が限定されているため、適切な場所で適切な方法を選択することが重要です。

ポイント
  • プレースホルダーはHTMLテンプレートのみで使用可能
  • JavaScriptコードではモジュールAPIを使用
  • セキュリティを考慮してPUBLIC_プレフィックスを活用

関連リンク

Last update at: 2025/09/08 20:32:07