--- title: 'Custom elements 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 `` [element](/docs/special-elements#svelte-options). ```svelte

Hello {name}!

``` Alternatively, use `tag={null}` to indicate that the consumer of the custom element should name it. ```js 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: ```js document.body.innerHTML = `

This is some slotted content

`; ``` By default, custom elements are compiled with `accessors: true`, which means that any [props](/docs/dot-svelte-files#attributes-and-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 ``. ```js 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](https://custom-elements-everywhere.com/). 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 `` element is inside an `{#if ...}` block. Similarly, including a `` 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