diff --git a/.changeset/green-pumpkins-ring.md b/.changeset/green-pumpkins-ring.md new file mode 100644 index 000000000000..20bed8e3471e --- /dev/null +++ b/.changeset/green-pumpkins-ring.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: better error messages for invalid HTML trees diff --git a/documentation/docs/98-reference/.generated/compile-errors.md b/documentation/docs/98-reference/.generated/compile-errors.md index 16cd361e52c5..fe71b0eef6e4 100644 --- a/documentation/docs/98-reference/.generated/compile-errors.md +++ b/documentation/docs/98-reference/.generated/compile-errors.md @@ -481,12 +481,12 @@ A component cannot have a default export ### node_invalid_placement ``` -%thing% is invalid inside `<%parent%>` +%message%. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components. ``` HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples: -- `

hello

world

` will result in `

hello

world

` for example (the `
` autoclosed the `

` because `

` cannot contain block-level elements) +- `

hello

world

` will result in `

hello

world

` (the `
` autoclosed the `

` because `

` cannot contain block-level elements) - `

option a
` will result in `` (the `
` is removed) - `
cell
` will result in `
cell
` (a `` is auto-inserted) diff --git a/documentation/docs/98-reference/.generated/compile-warnings.md b/documentation/docs/98-reference/.generated/compile-warnings.md index 775e0681c94f..f30244511455 100644 --- a/documentation/docs/98-reference/.generated/compile-warnings.md +++ b/documentation/docs/98-reference/.generated/compile-warnings.md @@ -643,12 +643,12 @@ Svelte 5 components are no longer classes. Instantiate them using `mount` or `hy ### node_invalid_placement_ssr ``` -%thing% is invalid inside `<%parent%>`. When rendering this component on the server, the resulting HTML will be modified by the browser, likely resulting in a `hydration_mismatch` warning +%message%. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warning ``` HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples: -- `

hello

world

` will result in `

hello

world

` for example (the `
` autoclosed the `

` because `

` cannot contain block-level elements) +- `

hello

world

` will result in `

hello

world

` (the `
` autoclosed the `

` because `

` cannot contain block-level elements) - `

option a
` will result in `` (the `
` is removed) - `
cell
` will result in `
cell
` (a `` is auto-inserted) diff --git a/packages/svelte/messages/compile-errors/template.md b/packages/svelte/messages/compile-errors/template.md index 38ff87d505a5..97bf0c30cc86 100644 --- a/packages/svelte/messages/compile-errors/template.md +++ b/packages/svelte/messages/compile-errors/template.md @@ -190,11 +190,11 @@ ## node_invalid_placement -> %thing% is invalid inside `<%parent%>` +> %message%. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components. HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples: -- `

hello

world

` will result in `

hello

world

` for example (the `
` autoclosed the `

` because `

` cannot contain block-level elements) +- `

hello

world

` will result in `

hello

world

` (the `
` autoclosed the `

` because `

` cannot contain block-level elements) - `

option a
` will result in `` (the `
` is removed) - `
cell
` will result in `
cell
` (a `` is auto-inserted) diff --git a/packages/svelte/messages/compile-warnings/template.md b/packages/svelte/messages/compile-warnings/template.md index bfa75ac7f02e..690681c172a3 100644 --- a/packages/svelte/messages/compile-warnings/template.md +++ b/packages/svelte/messages/compile-warnings/template.md @@ -40,11 +40,11 @@ ## node_invalid_placement_ssr -> %thing% is invalid inside `<%parent%>`. When rendering this component on the server, the resulting HTML will be modified by the browser, likely resulting in a `hydration_mismatch` warning +> %message%. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warning HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples: -- `

hello

world

` will result in `

hello

world

` for example (the `
` autoclosed the `

` because `

` cannot contain block-level elements) +- `

hello

world

` will result in `

hello

world

` (the `
` autoclosed the `

` because `

` cannot contain block-level elements) - `

option a
` will result in `` (the `
` is removed) - `
cell
` will result in `
cell
` (a `` is auto-inserted) diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index ad2919b34bd8..d23acf8bda29 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -1024,14 +1024,13 @@ export function mixed_event_handler_syntaxes(node, name) { } /** - * %thing% is invalid inside `<%parent%>` + * %message%. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components. * @param {null | number | NodeLike} node - * @param {string} thing - * @param {string} parent + * @param {string} message * @returns {never} */ -export function node_invalid_placement(node, thing, parent) { - e(node, "node_invalid_placement", `${thing} is invalid inside \`<${parent}>\``); +export function node_invalid_placement(node, message) { + e(node, "node_invalid_placement", `${message}. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.`); } /** diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js index e0d2710a08f0..88fe4e6afaee 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js @@ -12,8 +12,9 @@ export function ExpressionTag(node, context) { const in_template = context.path.at(-1)?.type === 'Fragment'; if (in_template && context.state.parent_element) { - if (!is_tag_valid_with_parent('#text', context.state.parent_element)) { - e.node_invalid_placement(node, '`{expression}`', context.state.parent_element); + const message = is_tag_valid_with_parent('#text', context.state.parent_element); + if (message) { + e.node_invalid_placement(node, message); } } diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js index fa6ca0f6e970..7454ab810354 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js @@ -114,15 +114,12 @@ export function RegularElement(node, context) { if (!past_parent) { if (ancestor.type === 'RegularElement' && ancestor.name === context.state.parent_element) { - if (!is_tag_valid_with_parent(node.name, context.state.parent_element)) { + const message = is_tag_valid_with_parent(node.name, context.state.parent_element); + if (message) { if (only_warn) { - w.node_invalid_placement_ssr( - node, - `\`<${node.name}>\``, - context.state.parent_element - ); + w.node_invalid_placement_ssr(node, message); } else { - e.node_invalid_placement(node, `\`<${node.name}>\``, context.state.parent_element); + e.node_invalid_placement(node, message); } } @@ -131,11 +128,12 @@ export function RegularElement(node, context) { } else if (ancestor.type === 'RegularElement') { ancestors.push(ancestor.name); - if (!is_tag_valid_with_ancestor(node.name, ancestors)) { + const message = is_tag_valid_with_ancestor(node.name, ancestors); + if (message) { if (only_warn) { - w.node_invalid_placement_ssr(node, `\`<${node.name}>\``, ancestor.name); + w.node_invalid_placement_ssr(node, message); } else { - e.node_invalid_placement(node, `\`<${node.name}>\``, ancestor.name); + e.node_invalid_placement(node, message); } } } else if ( diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/Text.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/Text.js index b60030f6389d..363a111b7dc6 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/Text.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/Text.js @@ -12,8 +12,9 @@ export function Text(node, context) { const in_template = context.path.at(-1)?.type === 'Fragment'; if (in_template && context.state.parent_element && regex_not_whitespace.test(node.data)) { - if (!is_tag_valid_with_parent('#text', context.state.parent_element)) { - e.node_invalid_placement(node, 'Text node', context.state.parent_element); + const message = is_tag_valid_with_parent('#text', context.state.parent_element); + if (message) { + e.node_invalid_placement(node, message); } } } diff --git a/packages/svelte/src/compiler/warnings.js b/packages/svelte/src/compiler/warnings.js index bd2895623050..de0805d7014f 100644 --- a/packages/svelte/src/compiler/warnings.js +++ b/packages/svelte/src/compiler/warnings.js @@ -763,13 +763,12 @@ export function event_directive_deprecated(node, name) { } /** - * %thing% is invalid inside `<%parent%>`. When rendering this component on the server, the resulting HTML will be modified by the browser, likely resulting in a `hydration_mismatch` warning + * %message%. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warning * @param {null | NodeLike} node - * @param {string} thing - * @param {string} parent + * @param {string} message */ -export function node_invalid_placement_ssr(node, thing, parent) { - w(node, "node_invalid_placement_ssr", `${thing} is invalid inside \`<${parent}>\`. When rendering this component on the server, the resulting HTML will be modified by the browser, likely resulting in a \`hydration_mismatch\` warning`); +export function node_invalid_placement_ssr(node, message) { + w(node, "node_invalid_placement_ssr", `${message}. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a \`hydration_mismatch\` warning`); } /** diff --git a/packages/svelte/src/html-tree-validation.js b/packages/svelte/src/html-tree-validation.js index 0ebf45e166c2..98e74b638f1e 100644 --- a/packages/svelte/src/html-tree-validation.js +++ b/packages/svelte/src/html-tree-validation.js @@ -135,59 +135,85 @@ const disallowed_children = { }; /** - * Returns false if the tag is not allowed inside the ancestor tag (which is grandparent and above) such that it will result + * Returns an error message if the tag is not allowed inside the ancestor tag (which is grandparent and above) such that it will result * in the browser repairing the HTML, which will likely result in an error during hydration. - * @param {string} tag + * @param {string} child_tag * @param {string[]} ancestors All nodes starting with the parent, up until the ancestor, which means two entries minimum - * @returns {boolean} + * @param {string} [child_loc] + * @param {string} [ancestor_loc] + * @returns {string | null} */ -export function is_tag_valid_with_ancestor(tag, ancestors) { - if (tag.includes('-')) return true; // custom elements can be anything +export function is_tag_valid_with_ancestor(child_tag, ancestors, child_loc, ancestor_loc) { + if (child_tag.includes('-')) return null; // custom elements can be anything - const target = ancestors[ancestors.length - 1]; - const disallowed = disallowed_children[target]; - if (!disallowed) return true; + const ancestor_tag = ancestors[ancestors.length - 1]; + const disallowed = disallowed_children[ancestor_tag]; + if (!disallowed) return null; if ('reset_by' in disallowed && disallowed.reset_by) { for (let i = ancestors.length - 2; i >= 0; i--) { const ancestor = ancestors[i]; - if (ancestor.includes('-')) return true; // custom elements can be anything + if (ancestor.includes('-')) return null; // custom elements can be anything // A reset means that forbidden descendants are allowed again if (disallowed.reset_by.includes(ancestors[i])) { - return true; + return null; } } } - return 'descendant' in disallowed ? !disallowed.descendant.includes(tag) : true; + if ('descendant' in disallowed && disallowed.descendant.includes(child_tag)) { + const child = child_loc ? `\`<${child_tag}>\` (${child_loc})` : `\`<${child_tag}>\``; + const ancestor = ancestor_loc + ? `\`<${ancestor_tag}>\` (${ancestor_loc})` + : `\`<${ancestor_tag}>\``; + + return `${child} cannot be a descendant of ${ancestor}`; + } + + return null; } /** - * Returns false if the tag is not allowed inside the parent tag such that it will result + * Returns an error message if the tag is not allowed inside the parent tag such that it will result * in the browser repairing the HTML, which will likely result in an error during hydration. - * @param {string} tag + * @param {string} child_tag * @param {string} parent_tag - * @returns {boolean} + * @param {string} [child_loc] + * @param {string} [parent_loc] + * @returns {string | null} */ -export function is_tag_valid_with_parent(tag, parent_tag) { - if (tag.includes('-') || parent_tag?.includes('-')) return true; // custom elements can be anything +export function is_tag_valid_with_parent(child_tag, parent_tag, child_loc, parent_loc) { + if (child_tag.includes('-') || parent_tag?.includes('-')) return null; // custom elements can be anything const disallowed = disallowed_children[parent_tag]; + const child = child_loc ? `\`<${child_tag}>\` (${child_loc})` : `\`<${child_tag}>\``; + const parent = parent_loc ? `\`<${parent_tag}>\` (${parent_loc})` : `\`<${parent_tag}>\``; + if (disallowed) { - if ('direct' in disallowed && disallowed.direct.includes(tag)) { - return false; + if ('direct' in disallowed && disallowed.direct.includes(child_tag)) { + return `${child} cannot be a direct child of ${parent}`; } - if ('descendant' in disallowed && disallowed.descendant.includes(tag)) { - return false; + + if ('descendant' in disallowed && disallowed.descendant.includes(child_tag)) { + return `${child} cannot be a child of ${parent}`; } + if ('only' in disallowed && disallowed.only) { - return disallowed.only.includes(tag); + if (disallowed.only.includes(child_tag)) { + return null; + } else { + return `${child} cannot be a child of ${parent}. \`<${parent_tag}>\` only allows these children: ${disallowed.only.map((d) => `\`<${d}>\``).join(', ')}`; + } } } - switch (tag) { + // These tags are only valid with a few parents that have special child + // parsing rules - if we're down here, then none of those matched and + // so we allow it only if we don't know what the parent is, as all other + // cases are invalid (and we only get into this function if we know the parent). + switch (child_tag) { case 'body': case 'caption': case 'col': @@ -196,18 +222,17 @@ export function is_tag_valid_with_parent(tag, parent_tag) { case 'frame': case 'head': case 'html': + return `${child} cannot be a child of ${parent}`; + case 'thead': case 'tbody': - case 'td': case 'tfoot': + return `${child} must be the child of a \`\`, not a ${parent}`; + case 'td': case 'th': - case 'thead': + return `${child} must be the child of a \`\`, not a ${parent}`; case 'tr': - // These tags are only valid with a few parents that have special child - // parsing rules - if we're down here, then none of those matched and - // so we allow it only if we don't know what the parent is, as all other - // cases are invalid (and we only get into this function if we know the parent). - return false; + return `\`\` must be the child of a \`\`, \`\`, or \`\`, not a ${parent}`; } - return true; + return null; } diff --git a/packages/svelte/src/internal/server/dev.js b/packages/svelte/src/internal/server/dev.js index 145b37479b3f..ecf4e67429ac 100644 --- a/packages/svelte/src/internal/server/dev.js +++ b/packages/svelte/src/internal/server/dev.js @@ -34,12 +34,11 @@ function stringify(element) { /** * @param {Payload} payload - * @param {Element} parent - * @param {Element} child + * @param {string} message */ -function print_error(payload, parent, child) { - var message = - `node_invalid_placement_ssr: ${stringify(parent)} cannot contain ${stringify(child)}\n\n` + +function print_error(payload, message) { + message = + `node_invalid_placement_ssr: ${message}\n\n` + 'This can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.'; if ((seen ??= new Set()).has(message)) return; @@ -72,15 +71,23 @@ export function push_element(payload, tag, line, column) { var ancestor = parent.parent; var ancestors = [parent.tag]; - if (!is_tag_valid_with_parent(tag, parent.tag)) { - print_error(payload, parent, child); - } + const child_loc = filename ? `${filename}:${line}:${column}` : undefined; + const parent_loc = parent.filename + ? `${parent.filename}:${parent.line}:${parent.column}` + : undefined; + + const message = is_tag_valid_with_parent(tag, parent.tag, child_loc, parent_loc); + if (message) print_error(payload, message); while (ancestor != null) { ancestors.push(ancestor.tag); - if (!is_tag_valid_with_ancestor(tag, ancestors)) { - print_error(payload, ancestor, child); - } + const ancestor_loc = ancestor.filename + ? `${ancestor.filename}:${ancestor.line}:${ancestor.column}` + : undefined; + + const message = is_tag_valid_with_ancestor(tag, ancestors, child_loc, ancestor_loc); + if (message) print_error(payload, message); + ancestor = ancestor.parent; } } diff --git a/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/_config.js b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/_config.js new file mode 100644 index 000000000000..4c45b2617965 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/_config.js @@ -0,0 +1,21 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + dev: true + }, + + html: `
`, + + recover: true, + + mode: ['hydrate'], + + errors: [ + 'node_invalid_placement_ssr: `` (form.svelte:1:0) cannot be a descendant of `` (main.svelte:5:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.' + ], + + warnings: [ + 'Hydration failed because the initial UI does not match what was rendered on the server' + ] +}); diff --git a/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/form.svelte b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/form.svelte new file mode 100644 index 000000000000..cddb6e37947d --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/form.svelte @@ -0,0 +1 @@ + diff --git a/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/main.svelte b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/main.svelte new file mode 100644 index 000000000000..8aea34332288 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr-ancestor/main.svelte @@ -0,0 +1,9 @@ + + + +
+ +
+ diff --git a/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr/_config.js b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr/_config.js index d815d10fc73e..bc4d709b1924 100644 --- a/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/invalid-html-ssr/_config.js @@ -12,8 +12,8 @@ export default test({ mode: ['hydrate'], errors: [ - 'node_invalid_placement_ssr: `

` (main.svelte:6:0) cannot contain `

` (h1.svelte:1:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.', - 'node_invalid_placement_ssr: `
` (main.svelte:9:0) cannot contain `` (form.svelte:1:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.' + 'node_invalid_placement_ssr: `

` (h1.svelte:1:0) cannot be a child of `

` (main.svelte:6:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.', + 'node_invalid_placement_ssr: `` (form.svelte:1:0) cannot be a child of `` (main.svelte:9:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.' ], warnings: [ diff --git a/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js b/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js index 9b2688711ded..71edff6a6836 100644 --- a/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js +++ b/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js @@ -6,6 +6,6 @@ export default test({ }, errors: [ - 'node_invalid_placement_ssr: `

` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:1:0) cannot contain `

` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:2:1)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.' + 'node_invalid_placement_ssr: `

` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:2:1) cannot be a child of `

` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:1:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.' ] }); diff --git a/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_expected_head.html b/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_expected_head.html index 27c37f693baa..6d9ea9de5f77 100644 --- a/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_expected_head.html +++ b/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_expected_head.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-2/errors.json b/packages/svelte/tests/validator/samples/invalid-node-placement-2/errors.json index 3d9786582343..abbded296af1 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-2/errors.json +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-2/errors.json @@ -1,7 +1,7 @@ [ { "code": "node_invalid_placement", - "message": "`

` is invalid inside `

`", + "message": "`

` cannot be a descendant of `

`. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.", "start": { "line": 4, "column": 3 diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-4/errors.json b/packages/svelte/tests/validator/samples/invalid-node-placement-4/errors.json index 4d637aed805a..727bf6c258ca 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-4/errors.json +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-4/errors.json @@ -1,7 +1,7 @@ [ { "code": "node_invalid_placement", - "message": "`` is invalid inside ``", + "message": "`` cannot be a descendant of ``. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.", "start": { "line": 4, "column": 3 diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-5/warnings.json b/packages/svelte/tests/validator/samples/invalid-node-placement-5/warnings.json index e85050beb721..59c73c4e736d 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-5/warnings.json +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-5/warnings.json @@ -1,7 +1,7 @@ [ { "code": "node_invalid_placement_ssr", - "message": "`` is invalid inside ``. When rendering this component on the server, the resulting HTML will be modified by the browser, likely resulting in a `hydration_mismatch` warning", + "message": "`` cannot be a child of ``. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warning", "start": { "line": 4, "column": 3 diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json b/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json index 63fc9c517e47..4849717e146d 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-6/errors.json @@ -1,7 +1,7 @@ [ { "code": "node_invalid_placement", - "message": "`

` is invalid inside `
`", + "message": "`
` cannot be a descendant of `
`. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.", "start": { "line": 16, "column": 3 diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-7/errors.json b/packages/svelte/tests/validator/samples/invalid-node-placement-7/errors.json index edfc158c9d56..a1422c001a0c 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-7/errors.json +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-7/errors.json @@ -1,7 +1,7 @@ [ { "code": "node_invalid_placement", - "message": "`

` is invalid inside `
`", + "message": "`
` must be the child of a `
`, not a `
`. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.", "start": { "line": 8, "column": 1 diff --git a/packages/svelte/tests/validator/samples/invalid-node-placement-8/errors.json b/packages/svelte/tests/validator/samples/invalid-node-placement-8/errors.json index 1127a7633624..d75d5d410521 100644 --- a/packages/svelte/tests/validator/samples/invalid-node-placement-8/errors.json +++ b/packages/svelte/tests/validator/samples/invalid-node-placement-8/errors.json @@ -1,7 +1,7 @@ [ { "code": "node_invalid_placement", - "message": "Text node is invalid inside `
`", + "message": "`<#text>` cannot be a child of ``. `` only allows these children: ``, `