--- title: "Svelte Snippets: Reuse Markup Without a New Component" author: "Danny Holloran" published: "2026-09-08T10:05:38.332Z" updated: "2026-09-08T10:05:38.332Z" url: "https://zyvop.com/svelte-snippets-reuse-markup-without-a-new-component-f4qhw" canonical: "https://danholloran.me/posts/svelte-snippets-reuse-markup-without-a-new-component" tags: ["JavaScript","svelte","TypeScript"] --- # Svelte Snippets: Reuse Markup Without a New Component ![Cover image]() You have a card layout that appears twice in the same component: once wrapped in a link, once bare. The markup is identical apart from the wrapper. For years the Svelte answer was to extract `Card.svelte`, import it, thread props through it, and accept a new file in your tree for six lines of HTML. That works, but it is a heavy tool for a light problem. A component brings its own module scope, its own props contract, and its own place in the file system. Sometimes you just want the markup twice. Svelte 5's snippets are the smaller tool, and once you see them as functions that return markup, most of the awkwardness in Svelte's old component-composition story goes away. ## A snippet is a function, and `{@render}` calls it The syntax is `{#snippet name(params)}...{/snippet}` to define, `{@render name(args)}` to call: ```svelte {#snippet figure(image)}
{image.caption}
{image.caption}
{/snippet} {#each images as image} {#if image.href} {@render figure(image)} {:else} {@render figure(image)} {/if} {/each} ``` Parameters behave like a normal function signature: any number of them, destructuring, default values. The one exception is rest parameters, which are not supported. Scope is lexical, and this is the part worth internalizing. A snippet can read anything in scope where it was declared — `