SvelteKitのonMount完全ガイド|SSRとの関係と正しい使い方
大平 恵美
大平 恵美
2025-02-12
SvelteKitの`onMount`は、コンポーネントがブラウザにマウントされた後に実行される関数です。SSR環境では`window`や`document`が存在しないため、直接使用するとエラーになります。本記事では、`onMount`の仕組みや正しい使い方、具体的なコード例を交えて解説します。SvelteKitのSSRとCSRの違いを理解し、効果的に`onMount`を活用しましょう!
あなた:

SvelteKitで開発をしています。on mountの説明をしてください。 例えば、scriptに直接windowを書いてもブラウザでは動作しないそうです。

ChatGPT:

SvelteKitにおける onMount の説明

1. onMount の役割

SvelteKitの onMount は、コンポーネントがブラウザにマウント(描画)された後に実行される関数です。これは サーバーサイドレンダリング(SSR) では動作せず、クライアントサイドでのみ機能します。

2. SSR(サーバーサイドレンダリング)とonMount

SvelteKitでは、ページのリクエストを受けると以下の流れでHTMLを生成します。

  • ユーザーがURLへアクセス
  • サーバーが +page.server.js(または .ts)と +page.svelte を処理
  • SSRによりHTMLが生成され、クライアントへ返される
  • この時点では onMount は実行されていない
  • クライアント側でコンポーネントがマウントされた後に onMount が実行

つまり、SSRではHTMLがすぐに生成されますが、ブラウザ側で実際にコンポーネントがマウントされた後でなければ onMount は動作しません。

3. onMount の具体的な用途

  • クライアントサイドでしか動かない処理を実行(例:window オブジェクトの使用)
  • ローカルストレージやセッションストレージのアクセス
  • 外部APIのデータフェッチ(ただし load 関数の方が推奨される場合も)
  • イベントリスナーの登録

4. onMount を使う際の注意点

  • script の中に window を直接書いても、SSRでは window が存在しないためエラーになる
  • onMount を使えば window を安全に利用できる
  • サーバーでは実行されないため、SSR前提の処理とは区別する

5. onMount の基本的な書き方

<script>
  import { onMount } from 'svelte';

  let data;

  onMount(() => {
    if (typeof window !== 'undefined') {
      data = localStorage.getItem('key') || 'デフォルト値';
    }
  });
</script>

<p>{data}</p>

このコードでは、onMount を使って localStorage からデータを取得し、コンポーネントに反映させています。


まとめ

  • onMountコンポーネントがブラウザでマウントされた後に実行される
  • SSRでは実行されない
  • ブラウザでしか動かない処理(window の操作、ローカルストレージ、イベントリスナー)に使う
  • onMount を適切に使うことで、クライアントサイドの処理を適切に分離できる

SvelteKitでは、SSRとクライアントサイドの違いを意識しながら onMount を活用すると、より適切なアプリ設計ができます!

あなた:

scriptにwindowを直接書いてもブラウザでは実行できないので、onMount内に記載して実行できるようにするということですか。

ChatGPT:

はい、その理解で正しいです!🎯

なぜ scriptwindow を直接書くと動かないのか?

SvelteKitでは、<script> の中のコードは サーバー(SSR)とクライアント(ブラウザ)の両方で実行される可能性がある ため、window を直接使うと SSR時に window が存在せずエラー になります。

<script>
  let width = window.innerWidth; // ❌ SSR時にエラーが発生する
</script>

<p>ウィンドウの幅: {width}px</p>

エラーの原因:
windowブラウザにしか存在しない ので、サーバー上(SSR)でこのコードを実行しようとすると window is not defined というエラーが発生する。


解決策: onMount 内に window を記載

onMount を使うと、SSRでは実行されず、クライアントサイドでのみ実行 されるため、安全に window を使うことができます。

<script>
  import { onMount } from 'svelte';

  let width;

  onMount(() => {
    width = window.innerWidth; // ✅ クライアントサイドでのみ実行される
  });
</script>

<p>ウィンドウの幅: {width}px</p>

正しい動作:

  • SSR時は onMount 内のコードは実行されないため、window にアクセスしようとしても問題なし。
  • クライアントサイドで onMount が発火し、そのタイミングで window.innerWidth を取得。

つまり、結論

windowdocument などの ブラウザ専用オブジェクト は、SSR時には存在しないので、onMount 内で使うのが正しい
onMountクライアントサイドでのみ実行される ため、SSRのエラーを回避できる
✔ ローカルストレージやイベントリスナーの登録など、ブラウザでのみ動く処理は onMount に記述する 🚀

これを意識すれば、SvelteKitでの開発がスムーズになります!🔥

あなた:

そもそもSveltKitがサーバーサイドでHTMLを生成するからこのようなことが起こるのですか。

ChatGPT:

はい、その通りです! 🎯
SvelteKitがサーバーサイドでHTMLを生成(SSR)するからこそ、このような問題が発生します。


なぜSSR(サーバーサイドレンダリング)で window を直接使うとエラーになるのか?

通常のフロントエンドフレームワーク(例えばReactのCSR)では、最初からクライアント(ブラウザ)でコードが実行 されるので windowdocument を自由に使えます。

しかし、SvelteKitは 初回のページロード時にサーバーでHTMLを生成して返す(SSR) という動作をするため、 サーバー環境には windowdocument が存在しません

そのため、例えば以下のコードは SSR時にエラーになります

<script>
  let width = window.innerWidth; // ❌ サーバーでは `window` が存在しないためエラー
</script>

<p>ウィンドウの幅: {width}px</p>

SvelteKitのSSRの仕組み

  1. ユーザーがページにアクセス
  2. SvelteKitのサーバーが +page.svelte+page.server.js を処理し、HTMLを生成
  3. 生成したHTMLをクライアントに送信
  4. ブラウザでクライアントサイドの処理(ハイドレーションや onMount など)が実行
  5. ブラウザで onMount の中の処理が動く(ここで windowdocument を安全に使える)

この流れの ②の段階ではサーバー上でコードが実行されるため、window が存在しない のがポイントです。


解決策: onMount を使う

onMount を使うと、クライアントサイドでのみコードを実行できるため、安全に window を利用できます。

<script>
  import { onMount } from 'svelte';

  let width;

  onMount(() => {
    width = window.innerWidth; // ✅ ブラウザ上でのみ実行
  });
</script>

<p>ウィンドウの幅: {width}px</p>

このコードなら問題なく動作する理由:

  • SSR時(サーバー上)では onMount 内のコードは実行されない ので、window にアクセスせずエラーにならない
  • クライアント(ブラウザ)にHTMLが送られた後に onMount が発火し、window を安全に利用できる

結論

SvelteKitはSSRを行うため、サーバー上では windowdocument は存在しない
そのため、window を直接使うとSSR時にエラーになる
onMount を使えば、クライアントサイドでのみ実行できるので安全
この違いを意識すれば、SSRとCSRのハイブリッド開発がスムーズにできる 🚀

SvelteKitのSSRの仕組みを理解すると、なぜ onMount が必要なのかがよく分かるようになりますね! 💡

あなた:

今までの会話を踏まえて、SveltKitにおけるouMountの仕組みを初学者に分かりやすく説明できるようにまとめてください。

ChatGPT:

SvelteKitにおける onMount の仕組みを分かりやすく解説 🚀


1. onMount とは?

onMount は、SvelteKitのコンポーネントが ブラウザ(クライアント)に表示されたときに実行される関数 です。

💡 ポイント

  • サーバー(SSR)では実行されない → つまり、HTMLがサーバーで生成されるときには onMount 内のコードは動かない。
  • ブラウザでのみ実行されるwindowdocument などのブラウザ専用のオブジェクトを安全に扱える。

2. なぜ onMount が必要なのか?

SvelteKitは 最初にサーバー側でHTMLを生成する(SSR) ので、
通常の <script>window などを書いてしまうと サーバー上で実行されてエラー になります。

エラーになる例(NGコード)

<script>
  let width = window.innerWidth; // ❌ SSR時に `window is not defined` エラー
</script>

<p>ウィンドウの幅: {width}px</p>
  • windowブラウザにしか存在しない ため、サーバー上でこのコードが実行されるとエラーになる!

3. onMount を使うとどうなる?

onMount を使えば、ブラウザに描画された後に実行される ため、安全に window を利用できます。

正しい使い方(OKコード)

<script>
  import { onMount } from 'svelte';

  let width;

  onMount(() => {
    width = window.innerWidth; // ✅ ブラウザでのみ実行されるため安全
  });
</script>

<p>ウィンドウの幅: {width}px</p>

このコードが正しく動く理由 👇

  1. SSR時(サーバー側でHTMLを生成する段階)では onMount 内のコードは実行されない(→ エラーにならない)
  2. ブラウザでページが表示された後に onMount が実行される(→ window を安全に使える)

4. onMount の主な使い道

onMount は、ブラウザでしか動かない処理 に使います。

よく使うケース

  • window を使った処理(例:window.innerWidth で画面サイズ取得)
  • ローカルストレージやセッションストレージの操作
  • 外部のライブラリ(例: Google Maps API)を使うとき
  • イベントリスナーの登録(例: window.addEventListener
  • アニメーションやDOM操作

5. onMount の具体例

(1)画面幅を取得する

<script>
  import { onMount } from 'svelte';

  let width = 0;

  onMount(() => {
    width = window.innerWidth; // ✅ クライアントでのみ実行
  });
</script>

<p>現在のウィンドウ幅: {width}px</p>

(2)ローカルストレージからデータを取得

<script>
  import { onMount } from 'svelte';

  let userName = 'ゲスト';

  onMount(() => {
    userName = localStorage.getItem('name') || 'ゲスト';
  });
</script>

<p>こんにちは、{userName} さん!</p>

(3)イベントリスナーを登録

<script>
  import { onMount } from 'svelte';

  let scrollY = 0;

  onMount(() => {
    const updateScroll = () => {
      scrollY = window.scrollY;
    };

    window.addEventListener('scroll', updateScroll);

    return () => {
      window.removeEventListener('scroll', updateScroll); // ✅ クリーンアップ
    };
  });
</script>

<p>スクロール位置: {scrollY}px</p>

6. onMount の注意点

注意すべきポイント

  1. SSRでは実行されない → もしSSRと連携したい場合は load 関数を使う
  2. イベントリスナーを登録したら onDestroy で解除する(メモリリークを防ぐ)
  3. 初期値を適切に設定するonMount が実行されるまで変数が undefined にならないようにする

7. まとめ

🔹 SvelteKitではSSR(サーバーサイドレンダリング)があるので、window などのブラウザ専用オブジェクトを直接使うとエラーになる
🔹 onMount を使うと、ブラウザでのみコードを実行できるので安全
🔹 ローカルストレージ、イベントリスナー、window などの処理は onMount 内に書く
🔹 onMount を適切に使えば、SSRとCSR(クライアントサイドレンダリング)をスムーズに組み合わせられる!


🛠 onMount を使って、SvelteKitをもっと便利に!

SvelteKitの強みは、SSRとCSRを組み合わせられること!
そのためには 「どこでコードが実行されるのか?」 を意識することが大事です。
onMount をうまく活用して、快適な開発を楽しんでください! 🚀✨