Ryan Chandler

Creating Custom Magic Variables in Alpine.js

3 min read

DRY code is important and it can be difficult to be completely DRY with your code, especially when you're using a front-end framework such as Alpine.

There a couple of ways to reduce code duplication, especially when it comes to utility functions for string manipulation or HTTP requests. With the release of Alpine v2.5 we can register custom magic variables that will allow us to reduce that duplication without copying and pasting functions, or adding a load of functions to the global namespace.

The entry point

All of Alpine's public API runs through a global window.Alpine object. Registering magic variables is no different.

A single call to Alpine.addMagicProperty will get you well on your way.

Alpine.addMagicProperty('property', function ($el) {

});

The first argument is the name of the magic property. If you're familiar with Alpine, you have probably already used $refs, $dispatch or $el.

The name you provide doesn't need to have any prefix, Alpine will automatically add a $ prefix so that it is more inline with the Alpine ones.

The second argument is the callback for the magic variable. This function will receive the root element for the component, not the component instance itself.

You can use this callback to return a scalar value such as a string, boolean or integer, or even return another function so that the magic variable can be invoked.

A good example

Nowadays I try to avoid using third-party libraries (where possible) and ship JavaScript that utilises native browser APIs. Let's take this approach and create a little helper for the Fetch API.

I want a magic variable called $post that will send a POST request to the URL provided as the first argument and pass along any data that I provide as the second argument.

Alpine.addMagicProperty('post', function () {
    return function (url, data = {}) {
        return fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            redirect: 'follow',
            body: JSON.stringify(data)
        });
    }
});

By returning a function from our callback, we can now invoke the $post property:

<button type="button" x-on:click="$post('/posts', { id: 1, title: 'Awesome New Post' })">
  Create Post
</button>

Pretty sweet, eh?

Sign off

This was just a short article to show you the API for creating custom magic variables / properties in your Alpine components.

Note: This API is not documented and you should be careful using it.

If you want to see some more examples of magic properties, Kevin Batdorf has created a collection of packages / helpers for you to use. Here is the GitHub link. (Huge shoutout to Kevin for being so active and helpful on the Alpine.js Discord too!)

If you create any cool helper functions, please share them on Twitter, I'm sure we'd all love to see them!