In Svelte we can use slots to compose components meaning our components can contain other components and elements to be more reusable like regular HTML.
Example.htmlCopy
<button>
<span>Child</span>
</button>
The <slot>
element lets us do that with components. If you’re familiar with React this is similar to the children
prop and Vue also has slots. We can provide a fallback if no content is provided.
Button.svelteCopy
<button>
<slot>Placeholder</slot>
</button>
<style>
button {
color: teal;
}
</style>
App.svelteCopy
<script>
import Button from './Button.svelte'
</script>
<Button>
<span>Child</span>
</Button>
<Button />
You can use named slots for more control over the placement of elements. If you want multiple elements going into the same slot use the <svelte:fragment>
element as the wrapper.
Button.svelteCopy
<button>
<slot name="icon"></slot>
<slot name="text"></slot>
</button>
App.svelteCopy
<script>
import Button from './Button.svelte'
</script>
<Button>
<span slot="icon">➕</span>
<span slot="text">Add</span>
</Button>
<Button>
<span slot="icon">💩</span>
<span slot="text">Delete</span>
</Button>
You might be asking when you’d use slots over regular components and the answer might be not often and that’s fine.
Here’s an example of slots and composition used in a real-world scenario in Svelte Cubed that’s a wrapper around Three.js so you write less code because it’s more declarative:
Example.svelteCopy
<script>
import * as SC from 'svelte-cubed';
import * as THREE from 'three';
</script>
<SC.Canvas>
<SC.Mesh geometry={new THREE.BoxGeometry()} />
<SC.PerspectiveCamera position={[1, 1, 3]} />
</SC.Canvas>
This is only a couple of lines of code compared to the equivalent Three.js code which has more than 20 lines of code and it’s harder to read.
There’s a lot more you can do with slot props but I encourage you to read the slots documentation because slots deserve their separate post.
Leave a Reply