Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hydration regression between 224 and 225 #12913

Closed
GauBen opened this issue Aug 19, 2024 · 9 comments · Fixed by #13073
Closed

Hydration regression between 224 and 225 #12913

GauBen opened this issue Aug 19, 2024 · 9 comments · Fixed by #13073
Labels
awaiting submitter needs a reproduction, or clarification bug
Milestone

Comments

@GauBen
Copy link
Contributor

GauBen commented Aug 19, 2024

Describe the bug

Hey! I found a regression between two Svelte 5 previews.

The following code produces an SSR hydration error in Svelte 5-225:

<!-- Card.svelte -->
<script lang="ts">
  import type { Snippet } from "svelte";

  const { header, children }: { header?: Snippet; children: Snippet } =
    $props();
</script>

<div class="card">
  {@render header?.()}
  <div class="body">
    {@render children()}
  </div>
</div>

Stacktrace

Uncaught (in promise) DOMException: Node.appendChild: Cannot add children to a Text
    child operations.js:101
    Card Card.svelte:34
    effect2 hmr.js:47
    update_reaction runtime.js:290
    update_effect runtime.js:423
    create_effect effects.js:121
    branch effects.js:329
    wrapper hmr.js:38
    update_reaction runtime.js:290
    update_effect runtime.js:423
    create_effect effects.js:121
    block effects.js:321
    wrapper hmr.js:28
    _page +page.svelte:382
    ...
Files
// operations.js
export function child(node) {
	if (!hydrating) {
		return get_first_child(node);
	}

	var child = /** @type {TemplateNode} */ (get_first_child(hydrate_node));

	// Child can be null if we have an element with a single child, like `<p>{text}</p>`, where `text` is empty
	if (child === null) {
        // It crashes there
		child = hydrate_node.appendChild(create_text());
	}

	set_hydrate_node(child);
	return child;
}
// compiled Card.svelte
function Card($$anchor, $$props) {
	$.check_target(new.target);
	$.push($$props, true, Card);
	$.validate_prop_bindings($$props, [], [], Card);
	$.next();

	var fragment = root();
	var div = $.sibling($.first_child(fragment));
	var node = $.sibling($.child(div)); // <-- Line 34

	$.snippet(node, () => $$props.header);

	var div_1 = $.sibling($.sibling(node));
	var node_1 = $.sibling($.child(div_1));

	$.snippet(node_1, () => $$props.children);
	$.next();
	$.reset(div_1);
	$.next();
	$.reset(div);
	$.next();
	$.append($$anchor, fragment);
	return $.pop({ ...$.legacy_api() });
}
compiled Card.svelte in 224
function Card($$anchor, $$props) {
	$.check_target(new.target);
	$.push($$props, true, Card);
	$.validate_prop_bindings($$props, [], [], Card);
	$.next();

	var fragment = root();
	var div = $.sibling($.first_child(fragment, true)); // Difference here!
	var node = $.sibling($.child(div));

	$.snippet(node, () => $$props.header);

	var div_1 = $.sibling($.sibling(node, true));
	var node_1 = $.sibling($.child(div_1));

	$.snippet(node_1, () => $$props.children);
	$.next();
	$.reset(div_1);
	$.next();
	$.reset(div);
	$.next();
	$.append($$anchor, fragment);
	return $.pop({ ...$.legacy_api() });
}

This has something to do with #12891

Reproduction

I hope the details I provided are enough to fix it, otherwise I will try to provide a complete repro

Logs

No response

System Info

Svelte next

Severity

blocking an upgrade

@GauBen
Copy link
Contributor Author

GauBen commented Aug 19, 2024

It happens because I have this config!

compilerOptions: {
  preserveWhitespace: true,
}

Removing it fixes the hydration issue

@dummdidumm dummdidumm added this to the 5.0 milestone Aug 19, 2024
@AleksandrIvanenko
Copy link

I also encountered a problem when switching to version 225, I don't know if it's the same problem or not, I can only attach a screenshot of the error. I don't fully understand what the problem is, some function is trying to find a sibling of a node that doesn't exist.

image

@trueadm
Copy link
Contributor

trueadm commented Aug 20, 2024

This is likely due to the changes in #12891.

@trueadm trueadm added the bug label Aug 20, 2024
@dummdidumm
Copy link
Member

I am not able to reproduce this. Please provide a reproduction repository.

Is one of you by any chance using some kind of HTML minifier in SvelteKit's handle hook? This could mean whitespace is removed where Svelte expects things to exist.

@dummdidumm dummdidumm added the awaiting submitter needs a reproduction, or clarification label Aug 21, 2024
@AleksandrIvanenko
Copy link

Yes, we are using the htmlnano and this is the cause.

@GauBen
Copy link
Contributor Author

GauBen commented Aug 21, 2024

I don't have a custom handle hook, I just used to have the preserveWhitespace option on. I'll try to create a minimal repro

@Rich-Harris
Copy link
Member

@GauBen any luck on that repro?

@GauBen
Copy link
Contributor Author

GauBen commented Aug 29, 2024

Yep, just did!

It's on https://github.com/GauBen/gautier.dev/tree/repro-12913

gh clone https://github.com/GauBen/gautier.dev
cd gautier.dev
git switch repro-12913
yarn
yarn dev
# -> http://localhost:5173/

@Rich-Harris
Copy link
Member

Rich-Harris commented Aug 29, 2024

Thanks! Whittled it down to this — investigating

<svelte:options preserveWhitespace />

{#each 'abc' as l}
  <div>{l}</div>
{/each}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting submitter needs a reproduction, or clarification bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants