You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This has been discussed a lot in the past (for example #627), but now with Svelte 5 released, I think we can take a look at this from a different angle, considering all the new Svelte 5 toys.
Describe the proposed solution
Let's consider a rather simple usecase - header that changes based on page. Most pages would want to use the same (default) header, while some can customize it. This could be achieved with snippets or with additional +page-<name>.svelte files, for example +page-appbar.svelte.
Pros: Code sharing between app bar and page, easy to use Cons: Not SSR-friendly. The page needs to first render before the snippet is created, which then needs to be sent to the layout for re-rendering.
Pros: SSR-friendly, intuitive (+page goes to children, +page-x goes to x) Cons: Need a communication mechanism to synchronize the page and named slots, as they don't share code.
Both of these method can sort-of be achieved in user land, but neither of them is great.
Syntactically I think this is great, but it would need a bit (more) help from the Svelte compiler to work.
<!-- +page.svelte -->
<script>
const { data, Header, Footer } =$props()
</script>
<Header> This is a header </Header>
Main content
<Footer> This is a footer </Footer>
<!-- +layout.svelte -->
<script>
const { children, header, footer } =$props()
</script>
<header> {@renderheader()} </header>
<main> {@renderchildren()} </main>
<footer> {@renderfooter()} </footer>
For this to work, a div with display: contents would need to be created that would hold the header/footer content, which is rendered inside the snippet, and a virtual component with this div as its target would be passed to the page:
<!-- +layout.svelte -->
<script>
import { initSlots } from'$lib/layout-slots.svelte.js';let { children } =$props();constslots=initSlots();
</script>
<!-- run page logic first to get slot snippets, the page should have no output.-->
{@renderchildren()}
<h1>{@renderslots.heading()}</h1>
{@renderslots.children()}
<!-- +page.svelte -->
<script>
import { setSlots } from'$lib/layout-slots.svelte.js';setSlots({ heading, children });
</script>
{#snippetheading()}
Hello there
{/snippet}
{#snippetchildren()}
Main slot content
{/snippet}
Describe the problem
This has been discussed a lot in the past (for example #627), but now with Svelte 5 released, I think we can take a look at this from a different angle, considering all the new Svelte 5 toys.
Describe the proposed solution
Let's consider a rather simple usecase - header that changes based on page. Most pages would want to use the same (default) header, while some can customize it. This could be achieved with snippets or with additional
+page-<name>.svelte
files, for example+page-appbar.svelte
.With snippets (demo)
Allow pages to export snippets:
that can then be used in layouts:
Pros: Code sharing between app bar and page, easy to use
Cons: Not SSR-friendly. The page needs to first render before the snippet is created, which then needs to be sent to the layout for re-rendering.
With additional files (demo)
Allow placing additional
+page
files that can be used in layouts:+page.svelte
+page-appbar.svelte
Pros: SSR-friendly, intuitive (
+page
goes tochildren
,+page-x
goes tox
)Cons: Need a communication mechanism to synchronize the page and named slots, as they don't share code.
Both of these method can sort-of be achieved in user land, but neither of them is great.
With magic (not demo)
Syntactically I think this is great, but it would need a bit (more) help from the Svelte compiler to work.
For this to work, a
div
withdisplay: contents
would need to be created that would hold the header/footer content, which is rendered inside the snippet, and a virtual component with this div as its target would be passed to the page:Conclusions
This is pretty unhinged, but would it be doable?
The text was updated successfully, but these errors were encountered: