{@html} tag is broken during hydration
Describe the bug
There is some weird behaviour with the {@html} tag when:
-
ssristrue - the value used in the {@html} tag is updated during component initialization in the browser
- the {@html} tag has text or element siblings
I have created a minimal repro (see below). Here's code that causes the weird behaviour:
<script>
import { browser } from "$app/environment";
let greeting = "You should not see me after hydration...";
/**
* Using the onMount approach will fix the issue,
* so it seems like there is something wrong
* in the component initialization
*/
// import { onMount } from "svelte";
// onMount(() => greeting = "G'day mate!");
if (browser) {
greeting = "G'day mate!";
}
</script>
<h2>Working:</h2>
<div>
{@html greeting}
</div>
<h2>Broken:</h2>
<div>
I don't work: {@html greeting}
</div>
<div>
<span>And neither do i:</span>
{@html greeting}
</div>
I tried to reproduce the bug in a svelte REPL, but with no luck. This makes me feel that the bug is a hydration and/or initialization problem, but i don't know enough of svelte-kit's inner behaviour to know for sure.
Reproduction
Link to minimal repro: https://github.com/MathiasWP/svelte-kit-at-html-bug Link to Stackblitz: https://stackblitz.com/edit/sveltejs-kit-template-default-qdzjsc
Logs
No response
System Info
System:
OS: macOS 11.6.7
CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
Memory: 54.57 MB / 8.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 18.12.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.19.2 - /usr/local/bin/npm
Browsers:
Brave Browser: 108.1.46.144
Chrome: 109.0.5414.87
Firefox: 104.0.2
Safari: 15.5
npmPackages:
@sveltejs/adapter-auto: ^1.0.0 => 1.0.2
@sveltejs/kit: ^1.0.0 => 1.1.4
svelte: ^3.54.0 => 3.55.1
vite: ^4.0.0 => 4.0.4
Severity
serious, but I can work around it
Additional Information
No response
Transferred to the svelte repo
Seems like this issue is still going on.
Here's another (very minimalistic) way to reproduce the issue: https://www.sveltelab.dev/iziz4nvzfq2g6l9
Just one file: +page.svelte
<script>
import { writable } from 'svelte/store';
import { browser } from '$app/environment';
const posts = [
{
id: 1,
content: '<span style="color:red;">Post One</span>'
},
{
id: 2,
content: '<span style="color:blue;">Post Two</span>'
}
];
const postId = writable(1);
if (browser) $postId = 2
$: currentPost = posts.find((post) => post.id === $postId);
</script>
<h1>Post ID: {currentPost.id}</h1>
<h2>{@html currentPost.content}</h2>
(Thanks @MacFJA)
https://github.com/sveltejs/kit/issues/12045