CORRECT008 · サーバー実行モジュールコードでの browser global
重大度: critical · カテゴリ: correctness
チェック内容
Section titled “チェック内容”必ずサーバーで実行されるコードでの browser 専用 global(window、document、localStorage、sessionStorage、navigator、location、history、screen、matchMedia、requestAnimationFrame、cancelAnimationFrame、IntersectionObserver、ResizeObserver、MutationObserver、alert、confirm、prompt)の読み取りを検出します:
.svelte.ts/.svelte.jsrunes モジュールや.svelteの<script module>ブロックのモジュールスコープ(サーバーで import された瞬間にクラッシュ)- SvelteKit のルート/フックファイル — トップレベル、
load/action/エンドポイント handler 本体、initフック(import 時またはリクエストごとにクラッシュ)
検出対象外: $app/environment の browser(エイリアス込み)や typeof window !== 'undefined' チェックでガードされたコード(early-return ガードを含む)、onMount/$effect/通常の関数内(モジュール評価時には実行されない)、裸の typeof window(throw しない)、自分で import/宣言した名前(const document = …)、handler 内にネストしたクロージャ(典型的にはクライアント側コールバック)、自身が ssr = false を export するファイル。
これらの global は Node に存在しません。モジュールスコープの window 参照はファイルがサーバーで import された瞬間に、load 内なら SSR リクエストのたびにクラッシュします — ReferenceError: window is not defined、コンパイラは一切警告しない本番 500 です。
export function load() { const stored = localStorage.getItem('filters'); // ❌ サーバーで ReferenceError
return {};}ブラウザアクセスをクライアント側へ移します:
<script> let stored = $state(null); $effect(() => { stored = localStorage.getItem('filters'); // ✅ effect はサーバーでは実行されない });</script>または明示的にガードします:
import { browser } from '$app/environment';
const stored = browser ? localStorage.getItem('filters') : null; // ✅