Svelte Client-side Component API

Creating a component

const component = new Component(options)

A client-side component — that is, a component compiled with generate: 'dom' (or the generate option left unspecified) is a JavaScript class.

import App from './App.svelte';


const app = new App({
	target: document.body,
	props: {
		// assuming App.svelte contains something like
		// `export let answer`:
		answer: 42
	}
});

The following initialisation options can be provided:

optiondefaultdescription
targetnoneAn HTMLElement or ShadowRoot to render to. This option is required
anchornullA child of the target to render the component immediately before
props{}An object of properties to supply to the component
contextnew Map()A Map of root-level context key-value pairs to supply to the component
hydratefalseSee below
introfalseIf true, will play transitions on initial render, rather than waiting for subsequent state changes

Existing children of the target are left where they are.

The hydrate option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the hydratable: true option.

Hydration of <head> elements only works properly if the server-side rendering code was also compiled with hydratable: true, which adds a marker to each element in the <head> so that the component knows which elements it's responsible for removing during hydration.

Whereas children of the The existing DOM doesn't need to match the component — Svelte will 'repair' the DOM as it goes.

import App from './App.svelte';


const app = new App({
	target: document.querySelector('#server-rendered-html'),
	hydrate: true
});

target are normally left alone, hydrate: true will cause any children to be removed. For that reason, the anchor option cannot be used alongside hydrate: true.

The existing DOM doesn't need to match the component — Svelte will 'repair' the DOM as it goes.

import App from './App.svelte';


const app = new App({
	target: document.querySelector('#server-rendered-html'),
	hydrate: true
});

$set

component.$set(props)

Programmatically sets props on an instance. component.$set({ x: 1 }) is equivalent to x = 1 inside the component's <script> block.

Calling this method schedules an update for the next microtask — the DOM is not updated synchronously.

component.$set({ answer: 42 });

$on

component.$on(event, callback)

Causes the callback function to be called whenever the component dispatches an event.

A function is returned that will remove the event listener when called.

const off = app.$on('selected', event => {
	console.log(event.detail.selection);
});


off();

$destroy

component.$destroy() : 

Removes a component from the DOM and triggers any onDestroy handlers.

component.prop
component.prop = value

If a component is compiled with accessors: true, each instance will have getters and setters corresponding to each of the component's props. Setting a value will cause a synchronous update, rather than the default async update caused by component.$set(...).

By default, accessors is false, unless you're compiling as a custom element.

console.log(app.count);
app.count += 1;

Custom element API

Svelte components can also be compiled to custom elements (aka web components) using the customElement: true compiler option. You should specify a tag name for the component using the <svelte:options> element.

<svelte:options tag="my-element" />


<script>
	export let name = 'world';
</script>


<h1>Hello {name}!</h1>
<slot></slot>

Alternatively, use tag={null} to indicate that the consumer of the custom element should name it.

import MyElement from './MyElement.svelte';

customElements.define('my-element', MyElement);

Once a custom element has been defined, it can be used as a regular DOM element:

document.body.innerHTML = `
	<my-element>
		<p>This is some slotted content</p>
	</my-element>
`;

By default, custom elements are compiled with accessors: true, which means that any props are exposed as properties of the DOM element (as well as being readable/writable as attributes, where possible).

To prevent this, add accessors={false} to <svelte:options>.

const el = document.querySelector('my-element');
// get the current value of the 'name' prop
console.log(el.name);
// set a new value, updating the shadow DOM
el.name = 'everybody';

Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as most frameworks. There are, however, some important differences to be aware of:

  • Styles are encapsulated, rather than merely scoped. This means that any non-component styles (such as you might have in a global.css file) will not apply to the custom element, including styles with the :global(...) modifier
  • Instead of being extracted out as a separate .css file, styles are inlined into the component as a JavaScript string
  • Custom elements are not generally suitable for server-side rendering, as the shadow DOM is invisible until JavaScript loads
  • In Svelte, slotted content renders lazily. In the DOM, it renders eagerly. In other words, it will always be created even if the component's <slot> element is inside an {#if ...} block. Similarly, including a <slot> in an {#each ...} block will not cause the slotted content to be rendered multiple times
  • The let: directive has no effect
  • Polyfills are required to support older browsers

Server-side component API

const result = Component.render(...)

Unlike client-side components, server-side components don't have a lifespan after you render them — their whole job is to create some HTML and CSS. For that reason, the API is somewhat different.

A server-side component exposes a render method that can be called with optional props. It returns an object with head, html, and css properties, where head contains the contents of any <svelte:head> elements encountered.

You can import a Svelte component directly into Node using svelte/register.

require('svelte/register');


const App = require('./App.svelte').default;


const { head, html, css } = App.render({
	answer: 42
});

The .render() method accepts the following parameters:

parameterdefaultdescription
props{}An object of properties to supply to the component
options{}An object of options

The options object takes in the following options:

optiondefaultdescription
contextnew Map()A Map of root-level context key-value pairs to supply to the component
const { head, html, css } = App.render(
	// props
	{ answer: 42 },
	// options
	{
		context: new Map([['context-key', 'context-value']])
	}
);