x-init Directive
Run code when the component initializes – perfect for fetching data or setting defaults.
What is x-init?
x-init runs a JavaScript expression when the component is first mounted. It’s the best place to set initial state, fetch data, or start timers. The expression can be a simple assignment, a function call, or even an async operation if you use async init() inside the data function.
When to Use
Use x-init whenever you need to perform actions after Alpine has mounted the component, such as:
– Fetching data from an API
– Setting default values based on external conditions
– Starting an interval or timer (remember to clean up when the component is destroyed)
– Focusing an input field on load
Basic Syntax
<div x-data="{ message: '' }" x-init="message = 'Hello Alpine'">
<span x-text="message"></span>
</div>Fetching Data on Init (async)
<div x-data="{
posts: [],
loading: true,
async init() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=5')
this.posts = await res.json()
this.loading = false
}
}">
<div x-show="loading">Loading...</div>
<template x-for="post in posts" :key="post.id">
<p x-text="post.title"></p>
</template>
</div>The async init() method works perfectly. Alpine will re‑render when the data changes. Showing a loading state improves user experience.
Timers and Cleanup
If you start a timer in x-init, you should clear it when the component is removed. Although Alpine 3 does not have a built‑in destroy hook, you can clear intervals manually or use $watch on a destroy signal.
<div x-data="{
timer: null,
init() {
this.timer = setInterval(() => {
console.log('tick')
}, 1000)
},
destroy() {
clearInterval(this.timer)
}
}">...</div>Can I use $refs inside x-init?
Yes! Once the component is mounted, all magic properties are available. You can safely do this.$refs.myInput.focus() inside an init method.
What order do x-data and x-init run?
x-data is processed first, then x-init runs. So you can access data properties defined in x-data from x-init.
💡 Tip
If you need to wait for multiple asynchronous tasks, use Promise.all inside async init().