Skip to content

Commit 5cf2b7a

Browse files
committed
ignore href when hydrating
1 parent 405e9da commit 5cf2b7a

File tree

5 files changed

+38
-21
lines changed

5 files changed

+38
-21
lines changed

.changeset/slimy-clouds-talk.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: ignore href attributes when hydrating

packages/svelte/src/internal/client/render.js

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,7 @@ export function attr(dom, attribute, value) {
25322532
// (we can't just compare the strings as they can be different between client and server but result in the
25332533
// same url, so we would need to create hidden anchor elements to compare them)
25342534
attribute !== 'src' &&
2535+
attribute !== 'href' &&
25352536
attribute !== 'srcset')
25362537
) {
25372538
if (value === null) {
@@ -2566,13 +2567,13 @@ function split_srcset(srcset) {
25662567
}
25672568

25682569
/**
2569-
* @param {HTMLSourceElement | HTMLImageElement} element_srcset
2570+
* @param {HTMLSourceElement | HTMLImageElement} element
25702571
* @param {string | undefined | null} srcset
25712572
* @returns {boolean}
25722573
*/
2573-
export function srcset_url_equal(element_srcset, srcset) {
2574-
const element_urls = split_srcset(element_srcset.srcset);
2575-
const urls = split_srcset(srcset || '');
2574+
export function srcset_url_equal(element, srcset) {
2575+
const element_urls = split_srcset(element.srcset);
2576+
const urls = split_srcset(srcset ?? '');
25762577

25772578
return (
25782579
urls.length === element_urls.length &&
@@ -2595,22 +2596,20 @@ export function srcset_url_equal(element_srcset, srcset) {
25952596
* @param {string | null} value
25962597
*/
25972598
function check_src_in_dev_hydration(dom, attribute, value) {
2598-
if (current_hydration_fragment !== null && (attribute === 'src' || attribute === 'srcset')) {
2599-
if (
2600-
(attribute === 'src' && !src_url_equal(dom.getAttribute('src') || '', value || '')) ||
2601-
(attribute === 'srcset' &&
2602-
!srcset_url_equal(/** @type {HTMLImageElement | HTMLSourceElement} */ (dom), value || ''))
2603-
) {
2604-
// eslint-disable-next-line no-console
2605-
console.error(
2606-
'Detected a src/srcset attribute value change during hydration. This will not be repaired during hydration, ' +
2607-
'the src/srcset value that came from the server will be used. Related element:',
2608-
dom,
2609-
' Differing value:',
2610-
value
2611-
);
2612-
}
2613-
}
2599+
if (!current_hydration_fragment) return;
2600+
if (attribute !== 'src' && attribute !== 'href' && attribute !== 'srcset') return;
2601+
2602+
if (attribute === 'srcset' && srcset_url_equal(dom, value)) return;
2603+
if (src_url_equal(dom.getAttribute(attribute) ?? '', value ?? '')) return;
2604+
2605+
// eslint-disable-next-line no-console
2606+
console.error(
2607+
`Detected a ${attribute} attribute value change during hydration. This will not be repaired during hydration, ` +
2608+
`the ${attribute} value that came from the server will be used. Related element:`,
2609+
dom,
2610+
' Differing value:',
2611+
value
2612+
);
26142613
}
26152614

26162615
/**
@@ -2778,7 +2777,7 @@ export function spread_attributes(dom, prev, attrs, lowercase_attributes, css_ha
27782777
if (
27792778
current_hydration_fragment === null ||
27802779
// @ts-ignore see attr method for an explanation of src/srcset
2781-
(dom[name] !== value && name !== 'src' && name !== 'srcset')
2780+
(dom[name] !== value && name !== 'src' && name !== 'href' && name !== 'srcset')
27822781
) {
27832782
// @ts-ignore
27842783
dom[name] = value;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!--ssr:0--><a href="/bar">foo</a><!--ssr:0-->
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
test(assert, target) {
5+
assert.equal(target.querySelector('a')?.getAttribute('href'), '/bar');
6+
}
7+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
let browser = typeof window !== 'undefined';
3+
</script>
4+
5+
<a href={browser ? '/foo': '/bar'}>foo</a>

0 commit comments

Comments
 (0)