Skip to content

Commit 5d05ca6

Browse files
authored
fix: suppress inner content warning when children prop is forwarded (#15269)
* fix: suppress inner content warning when children prop is forwarded When a +layout.svelte passes children to a child component via shorthand ({children}) or explicit prop (children={children}), the "inner content will not be rendered" warning no longer fires. Closes #13504 * refactor: extract has_children into utils.js to avoid logic duplication
1 parent d027236 commit 5d05ca6

File tree

4 files changed

+49
-5
lines changed

4 files changed

+49
-5
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: suppress false-positive inner content warning when children prop is forwarded to a child component

packages/kit/src/exports/vite/index.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import {
4040
} from './module_ids.js';
4141
import { import_peer } from '../../utils/import.js';
4242
import { compact } from '../../utils/array.js';
43-
import { should_ignore } from './static_analysis/utils.js';
43+
import { should_ignore, has_children } from './static_analysis/utils.js';
4444

4545
const cwd = posixify(process.cwd());
4646

@@ -112,10 +112,8 @@ const warning_preprocessor = {
112112
if (!filename) return;
113113

114114
const basename = path.basename(filename);
115-
const has_children =
116-
content.includes('<slot') || (isSvelte5Plus() && content.includes('{@render'));
117115

118-
if (basename.startsWith('+layout.') && !has_children) {
116+
if (basename.startsWith('+layout.') && !has_children(content, isSvelte5Plus())) {
119117
const message =
120118
`\n${colors.bold().red(path.relative('.', filename))}\n` +
121119
`\`<slot />\`${isSvelte5Plus() ? ' or `{@render ...}` tag' : ''}` +

packages/kit/src/exports/vite/static_analysis/utils.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
/**
2+
* Check if content has children rendering (slot, @render, or children prop forwarding)
3+
* @param {string} content - The markup content
4+
* @param {boolean} is_svelte_5_plus - Whether the project uses Svelte 5+
5+
* @returns {boolean}
6+
*/
7+
export function has_children(content, is_svelte_5_plus) {
8+
return (
9+
content.includes('<slot') ||
10+
(is_svelte_5_plus &&
11+
(content.includes('{@render') ||
12+
// children may be forwarded to a child component as a prop
13+
content.includes('{children}') ||
14+
content.includes('children={')))
15+
);
16+
}
17+
118
/**
219
* Check if a match position is within a comment or a string
320
* @param {string} content - The full content

packages/kit/src/exports/vite/static_analysis/utils.spec.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { expect, test, vi } from 'vitest';
22
import path from 'node:path';
3-
import { should_ignore } from './utils.js';
3+
import { should_ignore, has_children } from './utils.js';
44

55
// Mock the colors module to avoid issues in tests
66
vi.mock('kleur', () => ({
@@ -153,3 +153,27 @@ test.each([
153153
const result = should_warn_for_content(content, filename);
154154
expect(result).toBe(should_warn);
155155
});
156+
157+
test.each([
158+
['layout with @render children()', '{@render children()}', true],
159+
['layout with slot', '<slot />', true],
160+
['layout with named slot', '<slot name="default" />', true],
161+
[
162+
'layout forwarding children as shorthand prop',
163+
'<script>\n\tlet { children } = $props();\n</script>\n<Layout {children} />',
164+
true
165+
],
166+
[
167+
'layout forwarding children as explicit prop',
168+
'<script>\n\tlet { children } = $props();\n</script>\n<Layout children={children} />',
169+
true
170+
],
171+
[
172+
'layout with no children handling',
173+
'<script>\n\tlet { data } = $props();\n</script>\n<div>{data}</div>',
174+
false
175+
],
176+
['empty layout', '', false]
177+
])('layout children detection: %s', (_description, content, expected) => {
178+
expect(has_children(content, true)).toBe(expected);
179+
});

0 commit comments

Comments
 (0)