Reputation: 73
<script lang="ts">
let theme = localStorage.getItem("theme") ?? "light";
const handleClick = () => {
theme = (theme === "light" ? "dark" : "light");
console.log('classlist',document.documentElement.classList);
};
$:{
if (theme === "dark") {
document!.documentElement.classList.add("dark");
} else {
document!.documentElement.classList.remove("dark");
}
localStorage.setItem("theme", theme);
}
</script>
<button on:click={handleClick}>{theme === "light" ? "🌙" : "🌞"}</button>
when the button is clicked it prints the classlist fine, but I get document not defined when i add the reactive value.
Thank you @H.B for the answer:
<script lang="ts">
import { onMount } from "svelte";
let theme = localStorage.getItem("theme") ?? "light";
let flag = false;
onMount(()=>{
flag = true
})
$: if (flag) {
if ( theme === 'dark') {
document!.documentElement.classList.add("dark");
} else {
document!.documentElement.classList.remove("dark");
}
localStorage.setItem("theme", theme);
}
const handleClick = () => {
theme = (theme === "light" ? "dark" : "light");
console.log('classlist',document.documentElement.classList);
};
</script>
<button on:click={handleClick}>{theme === "light" ? "🌙" : "🌞"}</button>
this works as intended
Upvotes: 2
Views: 1877
Reputation: 185140
My guess would be that your build is server-side rendering. During SSR you cannot access any browser specific objects like the window
or document
.
You can e.g. try to use onMount
and set a flag to enable the reactive statement (add an if
for that after $:
).
Upvotes: 3