さとまたプログラミングラボ

SvelteKit

シンプルで高速なWebアプリケーションフレームワーク

SvelteKitとは?

日常での例え:「家具付きマンション」

素のJavaScript = 空き地

自由だけど、家を建てる道具も
材料も全部自分で用意が必要

SvelteKit = 家具付きマンション

ルーティング、データ取得、ビルド設定...
必要なものが最初から揃っている

「フレームワーク」とは?なぜ使う?

フレームワーク= Webアプリを作るための「土台」や「骨組み」

フレームワークなしで作ると:

  • ページ遷移の仕組みを自作する必要がある
  • ビルド設定(Webpack等)を自分で書く必要がある
  • SEO対策、パフォーマンス最適化も全部自分で

SvelteKitなら:これらが最初から用意されている!コードを書くことに集中できる

SvelteとSvelteKitの違い

Svelte:UIコンポーネントを作るためのライブラリ

SvelteKit:Svelteを使ったアプリを作るためのフレームワーク(ルーティング、ビルド等含む)

例えるなら:Svelte = レンガ、SvelteKit = レンガで家を建てる設計図と道具セット

SvelteKitでできること

高速パフォーマンス

特徴

コンパイル時に最適化、小さなバンドル

📁

ファイルベースルーティング

基本

routes/フォルダがそのままURL

📝

シンプルな構文

特徴

学習コストが低く、直感的

🔄

リアクティビティ

Svelte 5

$stateで状態管理が簡単

📦

load関数

重要

サーバーでデータ取得

📋

Form Actions

便利

フォーム処理が簡単

コード例

プロジェクト作成

npx sv createで開始

bash
# プロジェクト作成
npx sv create my-app

# 開発サーバー起動
cd my-app
npm install
npm run dev
プレビュー
✓ Project created
➜ Local: http://localhost:5173

基本的なページ

Svelteコンポーネントの構造

svelte
<!-- routes/+page.svelte -->
<script>
  let count = $state(0);

  function increment() {
    count++;
  }
</script>

<h1>Welcome to SvelteKit</h1>
<p>カウント: {count}</p>
<button onclick={increment}>+1</button>

<style>
  h1 { color: #ff3e00; }
  button {
    padding: 8px 16px;
    background: #ff3e00;
    color: white;
    border: none;
    border-radius: 4px;
  }
</style>
プレビュー

Welcome to SvelteKit

カウント: 0

コード解説:Svelteファイルの3つの部分

① <script> - JavaScript(ロジック)

let count = $state(0):変数を作成(初期値0)

function increment():ボタンクリック時に呼ばれる関数

② HTML部分 - 画面表示

{count}:変数の値を表示(変数が変わると自動更新)

onclick={increment}:クリック時にincrement関数を実行

③ <style> - CSS(見た目)

このコンポーネント専用のスタイル。他のページには影響しません。

リアクティビティ(Svelte 5)

$stateと$derivedで状態管理

svelte
<script>
  // リアクティブな状態
  let count = $state(0);
  let name = $state('');

  // 派生値(countが変わると自動更新)
  let doubled = $derived(count * 2);

  // エフェクト(依存値が変わると実行)
  $effect(() => {
    console.log('Count changed:', count);
  });
</script>

<input bind:value={name} placeholder="名前">
<p>こんにちは、{name || 'ゲスト'}さん</p>
<p>Count: {count}, Doubled: {doubled}</p>
プレビュー

こんにちは、ゲストさん

Count: 0, Doubled: 0

コード解説:Svelte 5の「Runes」

$state - 変更を追跡する変数

let count = $state(0);

この変数が変わると、使っている場所すべてが自動で再描画されます。

$derived - 他の値から計算される値

let doubled = $derived(count * 2);

countが1になったら、doubledは自動的に2になります。手動で更新する必要なし!

bind:value - 双方向バインディング

<input bind:value={name}>

入力欄に文字を打つとname変数が自動更新。nameを変えると入力欄の内容も変わります。

{name || "ゲスト"} - 条件付き表示

nameが空(未入力)の時は「ゲスト」を表示。入力があればその名前を表示します。

データ取得(load関数)

+page.server.tsでサーバーサイド取得

typescript
// routes/posts/+page.server.ts
export async function load() {
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  return {
    posts  // ページコンポーネントで使える
  };
}

// routes/posts/+page.svelte
<script>
  let { data } = $props();
</script>

{#each data.posts as post}
  <article>
    <h2>{post.title}</h2>
  </article>
{/each}
プレビュー

記事タイトル1

記事タイトル2

コード解説:サーバーとページの連携

ステップ1:サーバー側でデータ取得(+page.server.ts)

export async function load():ページが開かれる前に実行される

await fetch(...):APIからデータを取得(サーバー側で実行)

return {posts}:取得したデータをページに渡す

ステップ2:ページ側でデータ受け取り(+page.svelte)

let {data} = $props():load関数が返したデータを受け取る

data.posts:load関数で return したpostsにアクセス

処理の流れ

1. ユーザーが /posts にアクセス → 2. load関数がサーバーで実行 → 3. APIからデータ取得 → 4. ページに渡される → 5. 画面表示

Form Actions

サーバーサイドでフォーム処理

svelte
// routes/login/+page.server.ts
export const actions = {
  default: async ({ request }) => {
    const data = await request.formData();
    const email = data.get('email');
    const password = data.get('password');

    // 認証処理...

    return { success: true };
  }
};

// routes/login/+page.svelte
<form method="POST">
  <input name="email" type="email" required>
  <input name="password" type="password" required>
  <button type="submit">ログイン</button>
</form>
プレビュー

レイアウト

+layout.svelteで共通UI

svelte
<!-- routes/+layout.svelte -->
<script>
  let { children } = $props();
</script>

<header>
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
  </nav>
</header>

<main>
  {@render children()}
</main>

<footer>
  © 2024 My App
</footer>
プレビュー
HomeAbout
ページ内容
© 2024 My App

条件分岐とループ

Svelteのテンプレート構文

svelte
<script>
  let items = $state(['りんご', 'バナナ', 'オレンジ']);
  let show = $state(true);
</script>

<!-- 条件分岐 -->
{#if show}
  <p>表示中</p>
{:else}
  <p>非表示</p>
{/if}

<!-- ループ -->
<ul>
  {#each items as item, index}
    <li>{index + 1}. {item}</li>
  {/each}
</ul>
プレビュー

表示中

  • 1. りんご
  • 2. バナナ
  • 3. オレンジ

コード解説:どのように動作するか

① 変数の準備(<script>内)

let items = $state(['りんご', 'バナナ', 'オレンジ']);

$state([...]) で配列を作成。これにより、配列が変更されると自動的に画面も更新されます。

② 条件分岐({#if} 〜 {/if})

{#if show}
  <p>表示中</p> ← showがtrueの時に表示
{:else}
  <p>非表示</p> ← showがfalseの時に表示
{/if}

show = true なので「表示中」が表示されています。

③ ループ({#each} 〜 {/each})

{#each items as item, index}
  <li>{index + 1}. {item}</li>
{/each}

items の各要素を順番に処理:

  • item:現在の要素(「りんご」「バナナ」「オレンジ」)
  • index:順番(0, 1, 2)→ +1して「1, 2, 3」として表示

結果の組み立て

配列を1つずつ処理して、<li>1. りんご</li><li>2. バナナ</li><li>3. オレンジ</li> が順番に生成されます。

ディレクトリ構造

my-app/
├── src/
│   ├── routes/
│   │   ├── +layout.svelte    # 共通レイアウト
│   │   ├── +page.svelte      # トップページ (/)
│   │   ├── about/
│   │   │   └── +page.svelte  # /about
│   │   └── blog/
│   │       ├── +page.svelte  # /blog
│   │       └── [slug]/
│   │           └── +page.svelte # /blog/:slug
│   ├── lib/
│   │   └── components/       # 再利用コンポーネント
│   └── app.html
├── static/                   # 静的ファイル
└── package.json