sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
78.19k stars 4.09k forks source link

{@html} tag is broken during hydration #8213

Open MathiasWP opened 1 year ago

MathiasWP commented 1 year ago

Describe the bug

There is some weird behaviour with the {@html} tag when:

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

Rich-Harris commented 1 year ago

Transferred to the svelte repo

elron commented 1 year ago

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)

kvetoslavnovak commented 4 months ago

https://github.com/sveltejs/kit/issues/12045

seo-rii commented 3 weeks ago

When I wrap {@html ...} with {#key browser}, I could bypass this bug.