SvelteKitの$app/xxxの各種モジュールの使い方

$app/environment

import { browser, dev, building, version } from '$app/environment'

browser

ブラウザで実行された場合はtrueになる。

ブラウザの読み込みが完了するまでの間はfalseになるので注意。

<script>
  import { browser } from '$app/environment'
</script>

<h1>browser: {browser}</h1>

https://iwb.jp/s/sveltekit-app-module-how-to-use/browser/

dev

開発サーバー(npm run dev)が実行されているかどうか。

本番サーバーで実行されている場合はfalseになります。

NODE_ENVまたはMODEへの対応は保証されません。

<script>
  import { dev } from '$app/environment'
</script>

<h1>dev: {dev}</h1>

https://iwb.jp/s/sveltekit-app-module-how-to-use/dev/

building

SvelteKitはビルド中にアプリを実行して分析します。ビルドのプロセス中はtrueになります。

これはプリレンダリング中にも当てはまります。

<script>
  import { building } from '$app/environment'
</script>

<h1>building: {building}</h1>

version

svelte.config.js内のconfig.kit.version.nameに設定したものが表示される。

設定しないとDate.now()が表示される。

現在使用しているSvelteのバージョンが「4.1.2」のように返されるわけではない。

const config = {
  kit: {
    adapter: adapter({
      pages: 'build',
      assets: 'build',
      fallback: null,
      precompress: false,
    }),
    version: {
      name: '1.2.3',
    },
  },
  preprocess: vitePreprocess(),
}
<script>
  import { version } from '$app/environment'
</script>

<h1>version: {version}</h1>

https://iwb.jp/s/sveltekit-app-module-how-to-use/version/

$app/forms

import { applyAction, deserialize, enhance } from '$app/forms'

applyAction

applyActionは与えられたデータで現在のページのフォームプロパティを更新し、$page.statusを更新します。

エラーの場合は最も近いエラーページにリダイレクトします。

<script>
  import { applyAction } from '$app/forms'

  let name = ''

  function handleSubmit() {
    applyAction(name)
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <label for="name">名前:</label>
  <input type="text" id="name" bind:value={name} />
  <button type="submit">送信</button>
</form>

deserialize

フォーム送信のレスポンスをデシリアライズする関数。

JSON.parse()とほぼ同じ。(Success, Failureが定義されているという違いあり)

<script>
  import { deserialize } from '$app/forms'

  let str = '{"name": "John", "age": 35}'
  let dObj

  function handleDeserialize() {
    dObj = deserialize(str)
  }
</script>

<textarea bind:value={str} rows="4" cols="30"></textarea><br>
<button on:click={handleDeserialize}>deserialize</button>

{#if dObj}
  {(console.log(dObj), '')}
  <h1>結果</h1>
  <pre>{JSON.stringify(dObj, null, 2)}</pre>
{/if}

enhance

formのインタラクションを強化できる。

<script>
  import { enhance } from '$app/forms'
</script>

<form
  use:enhance={({ form, data, action, cancel, submitter }) => {
  }}
>
  <!-- formの内容 -->
</form>

$app/navigation

import {
    afterNavigate,
    beforeNavigate,
    disableScrollHandling,
    goto,
    invalidate,
    invalidateAll,
    preloadCode,
    preloadData
} from '$app/navigation'

afterNavigate

現在のコンポーネントがマウントされるとき、または新しいURLに移動するときに指定されたコールバックを実行するライフサイクル関数。

<script>
  import { afterNavigate } from '$app/navigation'

  afterNavigate(() => {
    console.log('&#x1f34e; 遷移前のページ')
  })
</script>

<!-- /afterNavigate/ -->
<h1>&#x1f34e; 遷移前のページ</h1>
<p><a href="/afterNavigateNext/">&#x1f34c; 遷移後のページへ</a></p>

<script>
  import { afterNavigate } from '$app/navigation'

  afterNavigate(() => {
    console.log('&#x1f34c; 遷移後のページ')
  })
</script>

<!-- /afterNavigateNext/ -->
<h1>&#x1f34c; 遷移後のページ</h1>
<p><a href="/afterNavigate/">&#x1f34e; 遷移前のページへ</a></p>

https://iwb.jp/s/sveltekit-app-module-how-to-use/afterNavigate/

beforeNavigate

新しいURLに移動する前に実行される。

<script>
  import { beforeNavigate } from '$app/navigation'

  beforeNavigate(() => {
    alert('iwb.jpのトップページに遷移します')
  })
</script>

<p><a href="https://iwb.jp/">iwb.jpのトップページへ</a></p>

https://iwb.jp/s/sveltekit-app-module-how-to-use/beforeNavigate/

disableScrollHandling

SvelteKitの組み込みスクロール処理が無効になります。

例えば /foo/ で2000px下にスクロールしたところにある /bar/ のリンクをクリックすると /bar/ の最上部から表示されますが、disableScrollHandling()を実行していると /bar/ でも2000px下位置から表示される。

前ページの位置のまま遷移させることなんてほとんどないので、用途はかなり限定される。

<script>
  import { afterNavigate, disableScrollHandling } from '$app/navigation'

  afterNavigate(() => {
    disableScrollHandling()
  })
</script>

<h1>disableScrollHandling Sample</h1>
<p>別ページに遷移後にスクロール位置が変更されません。</p>
<p><a href="/disableScrollHandlingNext/">別ページに遷移</a></p>

goto

指定のURLに遷移する。(Promiseを返す)

外部URLの場合はgoto(url) を呼び出す代わりに window.location = url を使用します。

<script>
  import { goto } from '$app/navigation'

  async function handleClick() {
    await new Promise(s => setTimeout(s, 3000))
    await goto('/version/')
  }
</script>

<button on:click|once={handleClick}>クリックから3秒後に/version/のページに遷移</button>

invalidate

ページが更新されたときに解決されるPromiseを返します。

SvelteKitはload関数を呼び出しますが、何かが変更されたと判断されないと呼び出されないので、そんなときはinvalidateでload関数を実行します。

https://learn.svelte.dev/tutorial/invalidation

invalidateAll

load関数を何に依存しているかに関係なく全て再実行させます。

https://learn.svelte.jp/tutorial/invalidate-all

preloadData

/foo に移動するために必要なコードとデータをプリロードします。

import { preloadData } from '$app/navigation'

preloadData('/foo');

HTMLにdata-sveltekit-preload-data属性を付けても同じことができる。

<a href="/foo" data-sveltekit-preload-data>foo link</a>

preloadCode

/bar に移動するために必要なコードをプリロードします。

import { preloadCode } from '$app/navigation'

preloadCode('/bar')

HTMLにdata-sveltekit-preload-code属性を付けても同じことができる。

<a href="/bar" data-sveltekit-preload-code>bar link</a>

$app/paths

svelte.config.jsで設定したbaseとassetsのパスを表示できる。

※ baseとassetsのデフォルトは空文字

ただし、vite run dev または vite run previewのときはassetsは「/_svelte_kit_assets」を返す。

<script>
  import { base, assets } from '$app/paths'
</script>

<h1>SvelteKit Paths</h1>
<p>Base Path: <code>{base}</code></p>
<p>Assets Path: <code>{assets}</code></p>
// svelte.config.js
const config = {
  kit: {
    paths: {
      base: '/foo',
      assets: 'https://iwb.jp',
    },
  },
}