Global Toast System

Learn how to build a global toast system with Spruce and Alpine.

Installation

Creating a store

Begin by creating a new store called toast.

Spruce.store('toast', {

})

This store needs to hold all of the toasts to be displayed, so add a new toasts property.

Spruce.store('toast', {
    toasts: [],
})

To make adding a new toast simple, define a new method called add(). This method should accept a single argument, message.

Spruce.store('toast', {
    toasts: [],
    add(message) {
        
    }
})

The new add(message) method needs to append the message to the toasts property. This can be done using the Array.push method.

Spruce.store('toast', {
    toasts: [],
    add(message) {
        this.toasts.push(message)
    }
})

Outputting toasts on the page

You can use Alpine to output the toasts on the page. The best way to do this is using Alpine's x-for directive.

<div x-data>
    <template x-for="toast in $store.toast.toasts">
        <div class="toast">
            <span x-text="toast"></span>
        </div>
    </template>
</div>

Removing toasts on click

To remove a toast when it has been clicked, you can add an event listener to the toast itself and modify the global store.

Begin by adding a new remove method to the toast store. This method should accept the index of the toast you want to remove.

Spruce.store('toast', {
    toasts: [],
    add(message) {
        this.toasts.push(message)
    },
    remove(index) {
        this.toasts.splice(index, 1)
    }
})

You will also need to pull the index into the x-for loop. Alpine uses the (item, index) syntax for this.

<div x-data>
    <template x-for="(toast, index) in $store.toast.toasts">
        <div @click="$store.toast.remove(index)" class="toast">
            <span x-text="toast"></span>
        </div>
    </template>
</div>

To improve the usability of this, you could wrap the toast in a <button> so that it is more semantically accurate.

Styling the toast component

Now that the toasts are being output on the page, go ahead and style them accordingly.

The most common approach to this is having them float in one position on the page, normally in the bottom corner or at the very top.

Last updated