How To Deal With “Window Is Not Defined” In SvelteKit

<lite-youtube videoid=“l1AB5f0Xyd4” playlabel=“How To Solve “Window Is Not Defined” In SvelteKit”>

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.

greet.ts
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.

+page.svelte
<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.

+page.svelte
<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.

+page.svelte
<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?

greet.ts
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.

+page.svelte
<script lang="ts">
  import { onMount } from 'svelte'

  onMount(async () => {
    const Greet = await import('greet')
    Greet.greet()
  })
</script>

That’s it! 😄

Support

If you want to support the content you're reading or watching on YouTube consider becoming a patreon starting low as 1$ per month.

Become a patreon
Subscribe For Updates
Found a mistake?

Every post is a Markdown file so contributing is simple as following the link below and pressing the pencil icon inside GitHub to edit it.

Edit on GitHub