SvelteKitの$app/stateでページ情報にアクセスした話

SvelteKitでは $app/state から page オブジェクトをインポートすることで、コンポーネントのどこからでも現在のURL・パラメータ・ルート情報にアクセスできます。


page オブジェクトの主なプロパティ

<script lang="ts">
  import { page } from '$app/state';
</script>

<!-- 現在のURL -->
<p>{page.url.pathname}</p>

<!-- ルートパラメータ(/posts/[id] の id など) -->
<p>{page.params.id}</p>

<!-- 現在のルートID -->
<p>{page.route.id}</p>

<!-- load関数が返したdata -->
<p>{page.data.user?.name}</p>
プロパティ 内容
page.url 現在のURL(URLオブジェクト)
page.params ルートパラメータ
page.route.id ルートID(例: /posts/[id]
page.data load 関数が返したデータ
page.status HTTPステータスコード
page.error エラー情報

実装例:ナビゲーションのアクティブ状態

page.url.pathname を使って、現在のページに対応するナビゲーションリンクをハイライトできます。

<!-- +layout.svelte -->
<script lang="ts">
  import { page } from '$app/state';
  import type { Snippet } from 'svelte';
  import type { LayoutData } from './$types';

  type Props = {
    data: LayoutData;
    children: Snippet;
  };

  let { data, children }: Props = $props();

  const navLinks = [
    { href: '/', label: 'ホーム' },
    { href: '/about', label: 'About' },
    { href: '/todo', label: 'TODO' },
    { href: '/upload', label: 'アップロード' },
  ];
</script>

<header>
  <nav>
    {#each navLinks as link}
      <a
        href={link.href}
        class:active={page.url.pathname === link.href}
      >
        {link.label}
      </a>
    {/each}
  </nav>

  {#if data.user}
    <span>{data.user.name}</span>
  {:else}
    <a href="/login">ログイン</a>
  {/if}
</header>

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

<style>
  nav {
    display: flex;
    gap: 1rem;
    margin-bottom: 1rem;
  }

  a.active {
    font-weight: bold;
    text-decoration: underline;
  }
</style>

class:active={page.url.pathname === link.href} の部分がポイントです。page はリアクティブなオブジェクトなので、ページ遷移のたびに自動で再評価され、アクティブなリンクのスタイルが切り替わります。


$app/stores との違い

Svelte 4時代は $app/stores$page ストアを使っていましたが、Svelte 5からは $app/statepage が推奨です。

Svelte 4(旧) Svelte 5(新)
インポート元 $app/stores $app/state
使い方 $page.url.pathname page.url.pathname
仕組み Svelteストア リアクティブオブジェクト(runes)

Svelte 5では $ プレフィックスなしでそのままアクセスできます。


まとめ

  • import { page } from '$app/state' でどのコンポーネントからでもページ情報にアクセスできる
  • page はリアクティブなのでページ遷移時に自動更新される
  • page.url.pathname を使ったナビゲーションのアクティブ状態の切り替えが典型的なユースケース
← トップページに戻る