diff --git a/.changeset/rare-cheetahs-laugh.md b/.changeset/rare-cheetahs-laugh.md new file mode 100644 index 0000000000..2637b50b3c --- /dev/null +++ b/.changeset/rare-cheetahs-laugh.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: always run `if` block code the first time diff --git a/packages/svelte/src/internal/client/dom/blocks/if.js b/packages/svelte/src/internal/client/dom/blocks/if.js index 6a880f28bc..36790c05c1 100644 --- a/packages/svelte/src/internal/client/dom/blocks/if.js +++ b/packages/svelte/src/internal/client/dom/blocks/if.js @@ -9,7 +9,7 @@ import { set_hydrating } from '../hydration.js'; import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js'; -import { HYDRATION_START_ELSE } from '../../../../constants.js'; +import { HYDRATION_START_ELSE, UNINITIALIZED } from '../../../../constants.js'; /** * @param {TemplateNode} node @@ -30,8 +30,8 @@ export function if_block(node, fn, elseif = false) { /** @type {Effect | null} */ var alternate_effect = null; - /** @type {boolean | null} */ - var condition = null; + /** @type {UNINITIALIZED | boolean | null} */ + var condition = UNINITIALIZED; var flags = elseif ? EFFECT_TRANSPARENT : 0; @@ -54,7 +54,7 @@ export function if_block(node, fn, elseif = false) { if (hydrating) { const is_else = /** @type {Comment} */ (anchor).data === HYDRATION_START_ELSE; - if (condition === is_else) { + if (!!condition === is_else) { // Hydration mismatch: remove everything inside the anchor and start fresh. // This could happen with `{#if browser}...{/if}`, for example anchor = remove_nodes(); diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_config.js b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_config.js new file mode 100644 index 0000000000..ffde9ee303 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_config.js @@ -0,0 +1,15 @@ +import { test } from '../../test'; + +// even {#if true} or {#if false} should be kept as an if block, because it could be {#if browser} originally, +// which is then different between client and server. +export default test({ + server_props: { + condition: true + }, + + props: { + condition: false + }, + + trim_whitespace: false +}); diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html new file mode 100644 index 0000000000..08a3809de9 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/_expected.html @@ -0,0 +1 @@ +
hello diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch-2/main.svelte b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/main.svelte new file mode 100644 index 0000000000..3136406698 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch-2/main.svelte @@ -0,0 +1,13 @@ + + +{#if condition} +foo
diff --git a/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte b/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte index c6799c5f95..552c434101 100644 --- a/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte +++ b/packages/svelte/tests/hydration/samples/if-block-mismatch/main.svelte @@ -2,7 +2,7 @@ let { condition } = $props(); -{#if true} +{#if condition}foo
{:else}bar