How to use events in Svelte

by Marc Radziwill | January 20, 2020 | 2 minutes to read

How you use events, implement custom component events and how you can bubble them up the DOM.


If you like this article, smile for a moment, please share it, follow me, check out my RSS feed and subscribe to my newsletter.


Intro to Svelte events

In my last article about Svelte, I talked about the advantages in general and how you can implement your first components, import them or display dynamic data. If you are new to Svelte, you should read my article "Why you should try Svelte".

Why you should try Svelte
Check out what you need to know for your first component in Svelte and learn the main advantages of version 3 from the compiler framework. Why you should try Svelte and how you can implement your first component

Today we talk about the cosmos of events in Svelte. I will cover DOM Events, Custom Events or Component Events "and a bit about the tricky parts.".

Tl;dr

In this article, I cover Svelte events, their use cases, how you implement custom component events and how you can bubble them up the DOM.

Tables of Contents

  1. Built-In Event handlers
  2. Component events
  3. Event forwarding
  4. What's next?

1. Built-In Event handlers

DOM Events

Event handlers are added to a component by on:{eventname} directive. To listen to the onclick event, you'll pass a function to the on:onclick attribute. You get the event object as an argument of your click handler.

1<script>
2 function handleClick(event) {
3 console.log('whooohoooo click event listener worked');
4 }
5</script>
6<button on:click="{handleClick}">Click me</button>

ℹ️ Performance hint

As the compiler takes care of the JavaScript generation, it also handles your coding style. In some frameworks, it's recommended to avoid inline event handlers for performance reasons. The compiler takes care of this. I got used to preventing inline functions; therefore, you won't see them in my examples. But feel free to use them in Svelte if you like.

Event modifiers

DOM events can have an event modifier. You can use them to tell the compiler to perform additional logic.

List of event modifiers

  • preventDefault — "calls event.preventDefault() before running the handler. Useful for client-side form handling, for example."
  • stopPropagation — "calls event.stopPropagation(), preventing the event from reaching the next element."
  • passive — "improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)"
  • capture — "fires the handler during the capture phase instead of the bubbling phase ()"
  • once — "remove the handler after the first time it runs."
  • self — "only trigger handler if event.target is the element itself."

Slow website and no clue why?

Get your free web performance checklist with personal feedback

Only until the end of July 2020!

Invest in your human capital and become a performance expert in only 7 modules.

What you get:

Component events

You can create custom events in svelte components and dispatch a message. To do so, you need to create a custom event dispatcher with the building function createEventDispatcher. createEventDispatcher has to be called when the component is instantiated for the first time.

If you are not familiar with event bubble and capture I recommend you to check out that topic as I don't cover it in my post.

As soon as you want to trigger the event, you use the dispatch function. This function takes a string and object as arguments. The string identifies the event, and the object is optional data that is available on the event object.

CustomEvent.svelte

1<script>
2 import { createEventDispatcher } from 'svelte';
3 const dispatch = createEventDispatcher();
4
5 // trigger event and send object
6 function sayHello() {
7 dispatch('eventName', {
8 text: 'nice event',
9 });
10 }
11</script>
12
13<button on:click="{sayHello}">Click for your custom event</button>

App.svelte

1<script>
2 import CustomEvent from './components/CustomEvent.svelte';
3</script>
4
5<CustomEvent on:eventName={(event, args) => { console.log(event, args); }} />

2. Event forwarding

If you write a custom component event, you have to keep in mind, that they don't bubble up the DOM like DOM events itself if you want to listen to an event that a nested component dispatched you to have to forward it from the intermediate components.

As you see below you Svelte has a shorthand for event forwarding. Your intermediate component forwards the event by using the same listener directive as before but without any event handler. In our case <CustomEvent on:eventName/> in Wrapper.svelte forwards the event triggered in CustomEvent.svelte.

App.svelte

1<script>
2 import Wrapper from './Wrapper.svelte';
3
4 function handleEvent(event) {
5 console.log(event);
6 }
7</script>
8
9<Wrapper on:eventName="{handleEvent}" />

Wrapper.svelte

1<script>
2 import CustomEvent from './CustomEvent.svelte';
3</script>
4
5<CustomEvent on:eventName />

CustomEvent.svelte

1<script>
2 import { createEventDispatcher } from 'svelte';
3 const dispatch = createEventDispatcher();
4
5 // trigger event and send object
6 function sayHello() {
7 dispatch('eventName', {
8 text: 'nice event',
9 });
10 }
11</script>
12
13<button on:click="{sayHello}">Click for your custom event</button>

DOM event forwarding

The event forwarding just presented can also be used for DOM events. If you have a custom component with a child that is listening to a DOM event, you can forward these events as well.

FancyImage.svelte

1<style>
2 img {
3 width: 100%;
4 }
5</style>
6
7<img
8 on:mouseover
9 src="https://images.unsplash.com/photo-1561303087-84f633edd5ea"
10 alt="Photo by @sebastiandumitru on unsplash"
11/>

App.svelte

1<script>
2 import FancyImage from './FancyImage.svelte';
3
4 function handleHover() {
5 alert('clicked');
6 }
7</script>
8
9<FancyImage on:mouseover="{handleHover}" />

4. What's next?

You find all the resources for this article on GitHub. Feel free to check it out, try some stuff or fork it.

Now you should be able to use events in Svelte like a pro! If you want to dive deeper, I recommend taking an hour or two of your time and going through the official tutorial.

If you like this article, smile for a moment, share it, follow me, check out my RSS feed and subscribe to my newsletter.

Cheers Marc