Description
Motivation
You can add a browser global to a .svelte
file that will cause it to error during SSR and often nothing will catch it right now. Sometimes the .svelte
file never gets loaded on the server during development making this easy to miss until it is shipped to production. I.e. if you navigate to the page via client-side routing you won't see the error. You have to refresh the page to see it
Description
browser globals should not be allowed directly inside a script block. There are a lot of other cases you can use them that are valid and so we can't catch all invalid cases, but hopefully we could catch the most obviously wrong ones
Examples
<!-- ✓ GOOD -->
<script>
import { onMount } from 'svelte';
onMount(() => {
const a = window.localStorage.getItem('myCat');
console.log(a);
});
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<!-- ✓ GOOD -->
<script>
import { BROWSER } from 'esm-env';
if (BROWSER) {
const a = window.localStorage.getItem('myCat');
console.log(a);
};
</script>
<!-- ✓ GOOD -->
<script>
import { browser } from '$app/environment';
if (browser) {
const a = window.localStorage.getItem('myCat');
console.log(a);
};
</script>
<!-- ✓ GOOD -->
<script>
$effect(() => {
const a = window.localStorage.getItem('myCat');
console.log(a);
});
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
<!-- ✗ BAD -->
<script>
const a = window.localStorage.getItem('myCat');
console.log(a);
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
Additional comments
Users may want to disable this rule if building a SPA. I think it's generally good practice even if you're building a SPA to leave this rule enabled in case you later want to enable SSR, but many users would feel that to be unnecessary overhead