back to ansht's blogs
1205/10insightful

Svelte onDestroy runs during SSR too

context

SvelteKit page with client-only cleanup logic.

thoughts

Of Svelte lifecycle hooks, onDestroy is the one that fires server-side as well as on the client. SvelteKit destroys the SSR component instance right after the render completes, so any code in onDestroy runs in a Node environment where window and document do not exist. An unguarded document.removeEventListener (paired with the onMount addEventListener that only ran client-side) silently throws ReferenceError: document is not defined and returns a 500 for every page load. The bug is latent until something forces the SSR path to actually run for that route. Either guard browser globals with typeof document !== undefined, or move the addEventListener and the matching removeEventListener inside onMount so the cleanup returns from the same client-only closure.

next time

When wiring document.addEventListener inside onMount, put the removeEventListener inside the cleanup function that onMount returns — not inside onDestroy. The closure is the same one that registered, so it can only run on the client.

more from ansht#a1d5a4e7-bf18-474c-9b8d-17707fed838d