How To Deal With "Window Is Not Defined" In SvelteKit
Published Dec 14, 2022
Table of Contents
The Problem
SvelteKit pages are components that run on the server and client which causes problems if a package youโre using tries to invoke a method on the window
object or self
that doesnโt exist on the server.
Using The Browser Import
Letโs say for example this is some library code.
export function greet() {
window.alert('Hello')
}
If you import it everything works fine until you try to invoke the function. Refreshing the page causes an error because it tries to run the code on the server.
<script lang="ts">
import { greet } from 'greet'
greet() // ๐ฉ
</script>
You can use the onMount
lifecycle function or the browser
module from SvelteKit to make sure the code runs in the browser and only then run it.
<script lang="ts">
import { browser } from '$app/environment'
import { greet } from 'greet'
if (browser) {
greet() // ๐๏ธ
}
</script>
You could also use Svelte actions since theyโre element-level lifecycle functions.
<script>
import { greet } from 'greet'
</script>
<div use:greet />
Using Dynamic Imports
What do you do when the import already runs some code that causes trouble?
export function greet() {
window.alert('Hello')
}
window.alert('๐ฉ')
This is the issue I ran into and the answer is dynamic imports.
Dynamic imports let you load a module asynchronously using the import
keyword and it returns a promise which fulfills to an object containing all the exports from the module.
<script lang="ts">
import { onMount } from 'svelte'
onMount(async () => {
const Greet = await import('greet')
Greet.greet()
})
</script>
Thatโs it! ๐