You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/site/content/guide/19-custom-elements.md

4.1 KiB

title
Custom elements

Custom elements are an emerging web standard for creating DOM elements that encapsulate styles and behaviours, much like Svelte components. They are part of the web components family of specifications.

Most browsers need polyfills for custom elements. See caniuse for more details

Svelte components can be used as custom elements by doing the following:

  1. Declaring a tag name. The value must contain a hyphen (hello-world in the example below)
  2. Specifying customElement: true in the compiler configuration
<!-- { filename: 'HelloWorld.html', repl: false } -->
<h1>Hello {name}!</h1>

<script>
	export default {
		tag: 'hello-world'
	};
</script>

Importing this file will now register a globally-available <hello-world> custom element that accepts a name property:

import './HelloWorld.html';
document.body.innerHTML = `<hello-world name="world"/>`;

const el = document.querySelector('hello-world');
el.name = 'everybody';

See svelte-custom-elements.surge.sh (source here) for a larger example.

The compiled custom elements are still full-fledged Svelte components and can be used as such:

el.get().name === el.name; // true
el.set({ name: 'folks' }); // equivalent to el.name = 'folks'

One crucial difference is that styles are fully encapsulated — whereas Svelte will prevent component styles from leaking out, custom elements use shadow DOM which also prevents styles from leaking in.

Using <slot>

Custom elements can use slots to place child elements, just like regular Svelte components.

Firing events

You can dispatch events inside custom elements to pass data out:

// inside a component method
const event = new CustomEvent('message', {
	detail: 'Hello parent!',
	bubbles: true,
	cancelable: true,
	composed: true // makes the event jump shadow DOM boundary
});

this.dispatchEvent(event);

Other parts of the application can listen for these events with addEventListener:

const el = document.querySelector('hello-world');
el.addEventListener('message', event => {
	alert(event.detail);
});

Note the composed: true attribute of the custom event. It enables the custom DOM event to cross the shadow DOM boundary and enter into main DOM tree.

Observing properties

Svelte will determine, from the template and computed values, which properties the custom element has — for example, name in our <hello-world> example. You can specify this list of properties manually, for example to restrict which properties are 'visible' to the rest of your app:

export default {
	tag: 'my-thing',
	props: ['foo', 'bar']
};

Compiler options

Earlier, we saw the use of customElement: true to instruct the Svelte compiler to generate a custom element using the tag and (optional) props declared inside the component file.

Alternatively, you can pass tag and props direct to the compiler:

const { js } = svelte.compile(source, {
	customElement: {
		tag: 'overridden-tag-name',
		props: ['yar', 'boo']
	}
});

These options will override the component's own settings, if any.

Transpiling