AlpineJS - Init event

October 12, 2023

I'm a huge fan of Alpine.js. One of the best features is the ability to break components and modules down into small reusable chunks of code that can easily be plugged into HTML. I generally prefer to install Alpine as a module and bundle it up with my main site javascript, but sometimes I need to break the compiled javascript into separate files. Understanding how and when to use the `alpine:init` event is the key to making this work.

Here's an example of what a typical "main" javascript file will look like, importing the main Alpine code and some plugins and modules. I like using standalone javascript files for each Alpine component instead of sprinkling javascript directly into the HTML. 

import Alpine from "alpinejs";
import collapse from '@alpinejs/collapse';
import focus from '@alpinejs/focus';
import interset from '@alpinejs/intersect';

import hero from "./modules/hero";
import gallery from "./modules/gallery";
import videoPlayer from "./modules/video-player";

window.Alpine = Alpine;

// setup for AlpineJs
Alpine.data("hero", hero);
Alpine.data("gallery", gallery);
Alpine.data("videoPlayer", videoPlayer);

Alpine.plugin(collapse);
Alpine.plugin(focus);
Alpine.plugin(interset);

Alpine.start();

Where it can get a little tricky is having Alpine components that you don't want included in your main javascript file. Maybe they are infrequently used or it's something that only exists in one place on your website. Regardless, you need a simple way to bundle that code outside your main javascript file and only load it when needed. It needs to get loaded and registered with Alpine so the HTML 'x-data' attribute can set off the component instantiation. 

In example below the `widget.html` file contains HTML referencing an Alpine component with the `x-data` attribute and a script tag to load the additional javascript file.

<div x-data="widget()" x-init="load()" class="relative"></div>

.....

<script src="/build/js/widgets.js"></script>

The 'widgets.js' file has a listener for `alpine:init` that waits until the main Alpine code has loaded and initialized and then registers the 'widget' code for use by the markup. By listening for `Alpine:init` event we can make sure that the javascript gets properly registered as early as possible so the HTML elements can access it when needed.

import widget from './modules/widget';

document.addEventListener('alpine:init', () => {
  Alpine.data("widget", widget);
});

Hope that tip helps somebody enjoy Alpine a little more. Stay tuned for more Alpine tips and tricks.