Skip to main content
When compiling a component as a custom element, the $host rune provides access to the host element, allowing you to (for example) dispatch custom events.
This rune is only available inside custom element components, and only on the client-side.

Signature

function $host<El extends HTMLElement = HTMLElement>(): El;
Returns the custom element host instance. You can specify a type parameter to get better type safety:
const host = $host<HTMLDivElement>();

Basic usage

Here’s an example of a stepper component that dispatches custom events:
/// file: Stepper.svelte
<svelte:options customElement="my-stepper" />

<script>
	function dispatch(type) {
		$host().dispatchEvent(new CustomEvent(type));
	}
</script>

<button onclick={() => dispatch('decrement')}>decrement</button>
<button onclick={() => dispatch('increment')}>increment</button>
The parent component can then listen to these events:
/// file: App.svelte
<script>
	import './Stepper.svelte';

	let count = $state(0);
</script>

<my-stepper
	ondecrement={() => count -= 1}
	onincrement={() => count += 1}
></my-stepper>

<p>count: {count}</p>

Dispatching events with detail

You can include data in your custom events using the detail property:
<svelte:options customElement="my-input" />

<script>
	let value = $state('');

	function handleChange() {
		$host().dispatchEvent(
			new CustomEvent('change', { 
				detail: { value } 
			})
		);
	}
</script>

<input bind:value oninput={handleChange} />

Accessing host attributes

You can also use $host() to access attributes set on the custom element:
<svelte:options customElement="my-element" />

<script>
	const host = $host();
	const theme = host.getAttribute('theme') || 'light';
</script>

<div class={theme}>
	<!-- component content -->
</div>

Use cases

$host is particularly useful for:
  • Dispatching custom events from web components
  • Reading attributes from the host element
  • Calling methods on the host element
  • Integrating with web component lifecycle hooks
  • Communicating with non-Svelte code
<svelte:options customElement="color-picker" />

<script>
	let color = $state('#ff3e00');

	function emitChange() {
		$host().dispatchEvent(
			new CustomEvent('colorchange', {
				detail: { color },
				bubbles: true
			})
		);
	}
</script>

<input 
	type="color" 
	bind:value={color} 
	oninput={emitChange} 
/>
Remember that $host() only works in components compiled with customElement option and only runs on the client-side.