DEV Community

Thomas Choi
Thomas Choi

Posted on

Does svelte5 have multi {@render} equivalent to ver.4’s multi named slot use inside +layout.svelte?

I hope to insert multiple different components into the specified {@render} of the upper layout at different routing sub-levels. Since I don’t know a simple way to pass these components to the default children props, my requirement is actually As the title of this question suggests, named slots are used in layouts. I currently use the following code to solve the needs, but I intuitively think that my way is bad and very circuitous, and I do not need to dynamically change the inserted components after loading the page, but I use additional code in order to pass these snippets The writable store and Context methods are added.

Hopefully someone can give me a better idea for my current approach, maybe there should be a direct way to pass props in the +page.svelte html area, but I can't find it.

//+layout.svelte

<script lang="ts">
  import { setContext, createRawSnippet } from 'svelte';
  import { writable } from 'svelte/store';

  const dummySnippet = (text: string) =>
    createRawSnippet(() => {
      return { render: () => text };
    });

  let { children } = $props();

  let slotLeft = writable(dummySnippet('LEFT'));
  let slotCenter = writable(dummySnippet('CENTER'));
  let slotRight = writable(dummySnippet('RIGHT'));

  setContext('LayoutSlot', { slotLeft, slotCenter, slotRight });
</script>

<winbox class="flex flex-row h-full w-full overflow-hidden">
  <listbox class="w-[400px]">
    {@render $slotLeft()}
  </listbox>

  <div class="flex-1 flex flex-col border-x">
    {@render $slotCenter()}
  </div>

  <div class="w-[350px]">
    {@render $slotRight()}
  </div>
</winbox>

{@render children()}
Enter fullscreen mode Exit fullscreen mode
// +page.svelte

<script lang="ts">
  import { onMount, getContext, type Snippet } from 'svelte';
  import type { Writable } from 'svelte/store';

  let {
    slotLeft,
    slotCenter,
    slotRight
  }: {
    slotLeft: Writable<Snippet>;
    slotCenter: Writable<Snippet>;
    slotRight: Writable<Snippet>;
  } = getContext('LayoutSlot');

  onMount(() => {
    $slotLeft = menuLeft;
    $slotCenter = mainContent;
    $slotRight = menuRight;
  });
</script>

{#snippet menuLeft()}
  <p>Left Menu Pending</p>
{/snippet}

{#snippet mainContent()}
  <p>Center Content Pending</p>
{/snippet}

{#snippet menuRight()}
  <p>Right Menu Pending</p>
{/snippet}

<children>TEST</children>

<!-- .... other option snippets from other routing-->
<!-- {#snippet foo1()} -->
<!-- {#snippet foo2()} -->
Enter fullscreen mode Exit fullscreen mode

In addition, when I use this method, I will receive a warning on the browser

[svelte] invalid_raw_snippet_renderThe render function passed to createRawSnippet should return HTML for a single element

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (5)

Collapse
 
fyodorio profile image
Fyodor

You should check out svelte’s reddit (or ask there) — I saw some similar discussions there, the community is pretty active in terms of v5 migration implications

Collapse
 
thomaschoi721 profile image
Thomas Choi

I have searched for similar topics, but they have nothing to do with layout. Unfortunately, I only found out after asking questions on reddit that I forgot to disconnect the proxy, which resulted in my reddit account being banned. . . I'm still trying to find a solution, thank you for your suggestions.
It’s true that I haven’t gotten used to the changes in version 5, but I like these new features, it just takes some time to adapt.

Collapse
 
max131 profile image
Mario

Just take the new svelte tutorial, it says that snippets inside a component are passed as a prop. svelte.dev/tutorial/svelte/implici...

Collapse
 
thomaschoi721 profile image
Thomas Choi • Edited

I found that I had seen this tutorial. According to my superficial knowledge, this method is only suitable for passing variables to component, but I can't find a way other than "context" to simplify my code.
The problem is that the general method of passing props from the +page.svelte file to +layout is in the html area. I hope that like version 4, I can use {@snippet render="xxx"} or in the html of +page. I specify the location of render.
Anyway, I will keep trying, thanks very much

Collapse
 
thomaschoi721 profile image
Thomas Choi

Okay, I'll go take a look right away, thank you for your help

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs