Sapper: Treat layout pages like components when using named slots

Created on 5 Sep 2019  路  10Comments  路  Source: sveltejs/sapper

Let's say I have a _layout.svelte like the following:

<slot name="layout-pre"></slot>

<div id="intermediate">Some other intermediate stuff.</div>

<slot></slot>

And now I have a child view (let's call it homepage.svelte which inherits that layout, which puts some stuff into the named slot, and the rest into the default slot:

<h1 slot="layout-pre">This should come before #intermediate.</h1>

<!-- When rendered, the div from above should get inserted here from the layout:
<div id="intermediate">Some other intermediate stuff.</div>
-->

<main>Since this doesn't use a named slot, it'll just get inserted into the unnamed slot above.</main>

Right now this is not allowed, and the following error is thrown: Element with a slot='...' attribute must be a descendant of a component or custom element. Are there technical or usage reasons why we wouldn't want to treat a layout like any other component with respect to slots?

Most helpful comment

Can someone show how to include a _customLayout.svelte as zakaria-chahboun suggests?

Example:

We have a route called test.
So we just create a folder named test, and inside of this folder we have our svelte files,
One is our router and the second is our custom layout, like so:

  • test

    • [id].svelte

    • _customLayout.svelte

The _customLayout.svelte is like this:

<slot name="sidebar"></slot>
<slot name="profile"></slot>

And the [id].svelte is like this:

<script context="module">
  export async function preload(page) {
    const { id } = page.params;
    return {id};
}
</script>

<script>
    import customLayout from "./_customLayout.svelte";
</script>

<customLayout>
    <div slot="sidebar">test</div>
</customLayout>

All 10 comments

I assumed this would work, only to get that error. I think this would be very useful in various situations.

Here's my use case (_layout.svelte):

<aside>
  <slot name="aside"></slot>
</aside>

<!-- other markup here, for various reasons -->

<main>
  <slot></slot>
</main>

With routes being components, shouldn't this be possible?

I guess it doesn't work because the Svelte compiler needs to know at compile-time which parent-component the slots will end up in.

was looking for this. I'm sad its not posible.

Well, there's nothing keeping us from writing our pages like

<Layout>
  <h1 slot="above">...</h1>
  <main>derp derp lalalala</main>
</Layout>

Is this the same issue / reason why slot props apparently aren't passed from layout files to components?

As mentioned on Stackoverflow here and here.

but, for example i was unsuccessfully trying to make this :

   <named slot>
 <Navcomponent in layout>
    <slot>

I mean, having 1 slot, then the regular layout in the middle with a navbar, and finally the regular slot. this for having each page to dinamicaly display stuff in two sites

The issue @silllli mentions is confusing me at the moment. Svelte's docs say that <slot>s are meant to be able to pass props

You have to do it in a regular way, by creating a custom layout: (_myLayout.svelte)
and include it in your index page.

Can someone show how to include a _customLayout.svelte as zakaria-chahboun suggests?

Can someone show how to include a _customLayout.svelte as zakaria-chahboun suggests?

Example:

We have a route called test.
So we just create a folder named test, and inside of this folder we have our svelte files,
One is our router and the second is our custom layout, like so:

  • test

    • [id].svelte

    • _customLayout.svelte

The _customLayout.svelte is like this:

<slot name="sidebar"></slot>
<slot name="profile"></slot>

And the [id].svelte is like this:

<script context="module">
  export async function preload(page) {
    const { id } = page.params;
    return {id};
}
</script>

<script>
    import customLayout from "./_customLayout.svelte";
</script>

<customLayout>
    <div slot="sidebar">test</div>
</customLayout>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

matt3224 picture matt3224  路  4Comments

Snugug picture Snugug  路  4Comments

milosdjakovic picture milosdjakovic  路  3Comments

BMorearty picture BMorearty  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments