From e03dae95da33b0149c24772290f301d72b519853 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 26 Aug 2024 20:12:07 +0200 Subject: [PATCH] fix: repair `href` attribute mismatches (#13032) * fix: repair `href` attribute mismatches The reasoning in #9662 turns out to be false: While it's true that the href would resolve to the same URL on the initial page, once you're doing a client-side navigation to a URL at a different depth, the relative path would now point to the wrong location. Therefore we need to repair href hydration mismatches fixes https://github.com/sveltejs/kit/issues/12254 * remove test * Revert "remove test" This reverts commit fa43304329ed27a7d08024ad86c694feb45c972a. * fix test * remove comment, since the rationale for skipping the attributes in question is covered by the one immediately below * fix * add test for specifically --------- Co-authored-by: Rich Harris --- .changeset/two-cats-approve.md | 5 +++++ .../src/internal/client/dom/elements/attributes.js | 8 ++++++-- .../samples/ignore-mismatched-href/_config.js | 4 ++-- .../samples/ignore-mismatched-href/main.svelte | 2 +- .../hydration/samples/img-src-mismatch/_config.js | 2 +- .../samples/repair-mismatched-a-href/_config.js | 11 +++++++++++ .../samples/repair-mismatched-a-href/_expected.html | 1 + .../samples/repair-mismatched-a-href/main.svelte | 5 +++++ 8 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 .changeset/two-cats-approve.md create mode 100644 packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_config.js create mode 100644 packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html create mode 100644 packages/svelte/tests/hydration/samples/repair-mismatched-a-href/main.svelte diff --git a/.changeset/two-cats-approve.md b/.changeset/two-cats-approve.md new file mode 100644 index 0000000000..7756dfdd67 --- /dev/null +++ b/.changeset/two-cats-approve.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: repair `href` attribute mismatches diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index 7e42efae11..672354669b 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -89,7 +89,11 @@ export function set_attribute(element, attribute, value, skip_warning) { if (hydrating) { attributes[attribute] = element.getAttribute(attribute); - if (attribute === 'src' || attribute === 'href' || attribute === 'srcset') { + if ( + attribute === 'src' || + attribute === 'srcset' || + (attribute === 'href' && element.nodeName === 'LINK') + ) { if (!skip_warning) { check_src_in_dev_hydration(element, attribute, value); } @@ -388,7 +392,7 @@ function check_src_in_dev_hydration(element, attribute, value) { w.hydration_attribute_changed( attribute, - element.outerHTML.replace(element.innerHTML, '...'), + element.outerHTML.replace(element.innerHTML, element.innerHTML && '...'), String(value) ); } diff --git a/packages/svelte/tests/hydration/samples/ignore-mismatched-href/_config.js b/packages/svelte/tests/hydration/samples/ignore-mismatched-href/_config.js index 9a7d9cadcf..6253e16705 100644 --- a/packages/svelte/tests/hydration/samples/ignore-mismatched-href/_config.js +++ b/packages/svelte/tests/hydration/samples/ignore-mismatched-href/_config.js @@ -10,10 +10,10 @@ export default test({ }, test(assert, target) { - assert.equal(target.querySelector('a')?.getAttribute('href'), '/bar'); + assert.equal(target.querySelector('link')?.getAttribute('href'), '/bar'); }, errors: [ - 'The `href` attribute on `...` changed its value between server and client renders. The client value, `/foo`, will be ignored in favour of the server value' + 'The `href` attribute on `` changed its value between server and client renders. The client value, `/foo`, will be ignored in favour of the server value' ] }); diff --git a/packages/svelte/tests/hydration/samples/ignore-mismatched-href/main.svelte b/packages/svelte/tests/hydration/samples/ignore-mismatched-href/main.svelte index de78109c00..fd5f2a038a 100644 --- a/packages/svelte/tests/hydration/samples/ignore-mismatched-href/main.svelte +++ b/packages/svelte/tests/hydration/samples/ignore-mismatched-href/main.svelte @@ -2,4 +2,4 @@ let { browser } = $props(); -foo + diff --git a/packages/svelte/tests/hydration/samples/img-src-mismatch/_config.js b/packages/svelte/tests/hydration/samples/img-src-mismatch/_config.js index 864bd4fac7..b30f652e3f 100644 --- a/packages/svelte/tests/hydration/samples/img-src-mismatch/_config.js +++ b/packages/svelte/tests/hydration/samples/img-src-mismatch/_config.js @@ -12,6 +12,6 @@ export default test({ assert.htmlEqual(target.innerHTML, ''); }, errors: [ - 'The `src` attribute on `...` changed its value between server and client renders. The client value, `client.jpg`, will be ignored in favour of the server value' + 'The `src` attribute on `` changed its value between server and client renders. The client value, `client.jpg`, will be ignored in favour of the server value' ] }); diff --git a/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_config.js b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_config.js new file mode 100644 index 0000000000..bc74f23aac --- /dev/null +++ b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_config.js @@ -0,0 +1,11 @@ +import { test } from '../../test'; + +export default test({ + server_props: { + browser: false + }, + + props: { + browser: true + } +}); diff --git a/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html new file mode 100644 index 0000000000..2f5b652fac --- /dev/null +++ b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/_expected.html @@ -0,0 +1 @@ +foo diff --git a/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/main.svelte b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/main.svelte new file mode 100644 index 0000000000..be01d05f8e --- /dev/null +++ b/packages/svelte/tests/hydration/samples/repair-mismatched-a-href/main.svelte @@ -0,0 +1,5 @@ + + +foo