svelte
svelte copied to clipboard
[AGAIN] Incorrect error message "... received an unexpected slot "default".
Describe the bug
received an unexpected slot "XXXXXX" for all the slots which were used in the component.
Logs
index.mjs:1701 <ts-divider> received an unexpected slot "default".
To Reproduce
<div class="ts-divider">
<!-- Text -->
{#if $$slots.default}
<div class="ts-divider__text">
<div class="ts-divider__text__start">
<div class="ts-divider__text__line"></div>
</div>
<div class="ts-divider__text__center">
<slot></slot>
</div>
<div class="ts-divider__text__end">
<div class="ts-divider__text__line"></div>
</div>
</div>
{/if}
<!-- / Text -->
<!-- Line Only -->
{#if !$$slots.default}
<div class="ts-divider__line"></div>
{/if}
<!-- / Line Only -->
</div>
Expected behavior
No warning message should appeared.
Stacktraces
If you have a stack trace to include, we recommend putting inside a <details> block for the sake of the thread's readability:
index.mjs:1701 <ts-divider> received an unexpected slot "default".
validate_slots @ index.mjs:1701
instance @ Divider.svelte:132
init @ index.mjs:1517
Divider @ Divider.svelte:18
(anonymous) @ Divider.svelte:18
(anonymous) @ Divider.svelte:18
Information about your Svelte project:
-
Your browser and the version: (e.x. Chrome 52.1, Firefox 48.0, IE 10): Chrome 90
-
Your operating system: (e.x. OS X 10, Ubuntu Linux 19.10, Windows XP, etc): Ubuntu 19.10
-
Svelte version (Please check you can reproduce the issue with the latest release!): ^3.38.1
-
Whether your project uses Webpack or Rollup: Rollup
Severity
It's not immediate just annoying warning messages.
Additional context
Re-open an new issue from Incorrect error message "... received an unexpected slot "default". #4546
@YamiOdymel it would be great if you could provide a repl (https://svelte.dev/repl) / github repo that could replicate this issue?
@YamiOdymel it would be great if you could provide a repl (https://svelte.dev/repl) / github repo that could replicate this issue?
I think someone has replied with a command to reproduce the issue
@tanhauhau Sadly, the bug isn't fixed. I think this needs to be reopened.
Simple reproduction:
npm init svelte@next slot-test && cd slot-test && npm i && npm run dev+ open the browser dev-console. You don't need to write a single char of code to trigger it :)
@tanhauhau just a new svelte-kit project!
@YamiOdymel @frederikhors yup.
@YamiOdymel just want to confirm, whether the one you are reporting is the same root cause of the issue from svelte kit
@tanhauhau shared some notes with me. Putting them here for reference
for kit issue, it's because of code like this:
<script>
let components = [Layout, Route];
</script>
<svelte:component this={components[0]} {...(props_0 || {})}>
{#if components[1]}
<svelte:component this={components[1]} {...(props_1 || {})}>
{#if components[2]}
<svelte:component this={components[2]} {...(props_2 || {})}/>
{/if}
</svelte:component>
{/if}
</svelte:component>
the Route component receives a default slot of
{#if components[2]}
<svelte:component this={components[2]} {...(props_2 || {})}/>
{/if}
even if components[2] is falsy.
but Route isn't expecting any slot, therefore the warning.
because of how slot is implemented right now, we pass the whole "{#if}" block into the default <slot/>, doesn't care whether the if block condition is true / false.
and the runtime warning checks if something is passed into the slot, even when the "something" renders nothing.
so, if we have a lot of __layout.svelte components, the generated code will be as many levels deep, thus when visiting a "shallow" route, you'll hit the "<Routes> received an unexpected slot "default"" warning
2 approaches:
- suppress the warning (there's no such option in svelte yet)
- support passing {#if} into slot, as in able to know that there'll be no content, if the condition is false, therefore do not warn + render slot fallback (https://github.com/sveltejs/svelte/issues/6218)
Hey @benmccann! Thank you for the explanation.
Wouldn't the following resolve the issue in kit?
<svelte:component this={components[0]} {...(props_0 || {})}>
{#if components[1]}
{#if components[2]}
<svelte:component this={components[1]} {...(props_1 || {})}>
<svelte:component this={components[2]} {...(props_2 || {})}/>
</svelte:component>
{:else}
<svelte:component this={components[1]} {...(props_1 || {})} />
{/if}
{/if}
</svelte:component>
If so, then https://github.com/sveltejs/kit/issues/981 can be resolved on its own.
@ebeloded That's causes component[1] to unnecessarily remount if only component[2] changes, which is unexpected behaviour for end-users and could have side effects for transitions/animations.
@benmccann Approach #2 (passing #if into slot) might also resolve $$slots with slot forwarding
For the records, This can also happen if one uses pug for writing the html, and accidentally calls the component like this: MyComponent (... my attribs ...), aka, have a whitespace between the component name and the brackets. Remove the whitespace and the message will disappear.
No fix yet? This is an extremely sad state of affairs.