Use svelte:element to dynamically render an HTML element.
<script>
let { level = 1, title = 'Todo List' } = $props();
</script>
<svelte:element this={level === 1 ? 'h1' : 'h2'}>
{title}
</svelte:element>
Svelte supports a set of special elements to work with the page around a component.
In this example, we'll briefly review Svelte's special elements.
Use svelte:element to dynamically render an HTML element.
<script>
let { level = 1, title = 'Todo List' } = $props();
</script>
<svelte:element this={level === 1 ? 'h1' : 'h2'}>
{title}
</svelte:element>
Use svelte:window to listen for window events or bind to a window property. Svelte takes care of removing listeners, and won't access window on the server.
<script>
let scrollY = $state(0);
</script>
<svelte:window bind:scrollY />
<p>You've scrolled {scrollY} pixels through your todos.</p>
Use svelte:body and svelte:document to listen for events on the body or document.
<script>
let lastKey = $state('');
function handleKeydown(event) {
lastKey = event.key;
}
</script>
<svelte:document onkeydown={handleKeydown} />
<svelte:body onclick={() => lastKey = ''} />
<p>Last key: {lastKey}</p>
Use svelte:head to add contents to the document's <head>.
<svelte:head>
<title>Todo List</title>
</svelte:head>
Use svelte:options to specify compiler options for a component. runes explicitly enables runes mode.
<svelte:options runes={true} />
<h1>Todo List</h1>
In runes mode, component references are reactive. Render a variable directly instead of using svelte:component.
<script>
import Todo from './Todo.svelte';
import CompletedTodo from './CompletedTodo.svelte';
let { todo } = $props();
let Component = $derived(
todo.completed ? CompletedTodo : Todo,
);
</script>
<Component {...todo} />
For recursive components, import the component into itself and render it by name instead of using svelte:self. Snippets replace named slots and svelte:fragment.
Further reading on this topic.