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:
option | default | description |
target | none | An HTMLElement or ShadowRoot to render to. This option is required |
anchor | null | A child of the target to render the component immediately before |
props | {} | An object of properties to supply to the component |
context | new Map() | A Map of root-level context key-value pairs to supply to the component |
hydrate | false | See below |
intro | false | If 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:
parameter | default | description |
props | {} | An object of properties to supply to the component |
options | {} | An object of options |
The options object takes in the following options:
option | default | description |
context | new 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']])
}
);