Working with events in Svelte
By Flavio Copes
Learn how to work with events in Svelte 5: onclick-style attributes for DOM events, preventDefault and stopPropagation, and callback props between components.
Listening to DOM events
In Svelte 5 you listen to DOM events with attributes that look like the browser ones: onclick, onmouseenter, onmousemove, and so on.
For example, to listen to the click event, you pass a function to the onclick attribute.
Here’s an example with the handling function defined inline:
<button onclick={() => {
alert('clicked')
}}>Click me</button>
and here’s another example with the handling function defined in the script section of the component:
<script>
const doSomething = () => {
alert('clicked')
}
</script>
<button onclick={doSomething}>Click me</button>
I prefer inline when the code is not too verbose. If it’s just 2-3 lines, for example, otherwise I’d move that up in the script section.
Svelte passes the event handler as the argument of the function, which is handy if you need to stop propagation or to reference something in the Event object:
<script>
const doSomething = event => {
console.log(event)
alert('clicked')
}
</script>
<button onclick={doSomething}>Click me</button>
Now, I mentioned “stop propagation”. That’s a very common thing to do, to stop form submit events for example. Call the methods on the event object:
<script>
const doSomething = event => {
event.preventDefault()
event.stopPropagation()
alert('clicked')
}
</script>
<button onclick={doSomething}>Click me</button>
Older Svelte code used on:click and modifiers like on:click|preventDefault. Svelte 5 still compiles that syntax (with a deprecation warning in runes mode), but modifiers don’t exist for onclick. For new components, use onclick and call preventDefault() / stopPropagation() yourself. The capture modifier has a direct replacement, onclickcapture, which runs the handler in the capturing phase. The old once and self modifiers have no attribute equivalent, so you write that logic inside the handler.
Creating your events in components
What’s interesting is that we can create custom events in components.
In Svelte 5 the preferred way is a callback prop. The child receives a function from the parent and calls it when something happens:
<script>
let { onmessage } = $props()
const send = () => {
onmessage?.('hello')
}
</script>
<button onclick={send}>Send</button>
Now the parent can use it like this:
<script>
import Child from './Child.svelte'
</script>
<Child onmessage={value => {
console.log(value)
}} />
You can pass an object the same way:
<script>
let { onmessage } = $props()
const value = 'something'
const send = () => {
onmessage?.({
someProperty: value
})
}
</script>
<button onclick={send}>Send</button>
Older components used createEventDispatcher from svelte and on:eventName on the parent. Svelte 5 marks that API as deprecated. It still works, but prefer callback props in new code. For more on how parent and child talk to each other, see props in Svelte.
Want me to talk about your product? You can sponsor this site.