Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Debugging and common pitfalls

Most Alpine errors come down to three causes: a typo in an expression, the wrong startup order, and elements that are visible before Alpine starts. Here is how to recognize and fix them.

Console messages

When an expression in a directive fails, Alpine logs an "Alpine Expression Error" warning with the error text, the expression and the element:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<div x-data="{ tasks: ['Buy milk'] }">
  <p x-text="taks.length"></p>
</div>

Below the example you see the error: taks is not defined and the expression taks.length. A typo in a name is the most common cause. In the browser, open the developer tools console: there the message is clickable and leads to the element.

x-cloak: flicker on load

The Alpine script runs after the browser has displayed the HTML. Elements with x-show="false" can flash for a split second: a modal or a menu appears and disappears. The x-cloak directive hides an element until Alpine starts — Alpine removes it on start. But you have to add the CSS rule for it yourself:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<style>
  [x-cloak] { display: none !important; }
</style>
 
<div x-data="{ open: false }">
  <button @click="open = !open">Menu</button>
  <ul x-show="open" x-cloak>
    <li>Edit</li>
    <li>Delete</li>
  </ul>
</div>

The menu does not show up while the page loads, even on a slow connection. The [x-cloak] rule goes into the site's shared CSS in the <head>, and x-cloak goes on everything hidden by default.

Startup order

SymptomCauseFix
Directives do nothing at allThe script has no defer, or Alpine.start() is not calledAdd defer, call Alpine.start()
todos is not definedAlpine.data registered after startRegister in alpine:init or before Alpine.start()
A plugin does nothingThe plugin script is below AlpineLoad plugins above Alpine
Everything fires twiceAlpine is loaded twiceKeep one way of loading

Inspecting component data

To see what is in the data right now, print it on the page. JSON.stringify from the "JSON" lesson of the tutorial makes the object readable:

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
 
<div x-data="{ title: '', tasks: ['Buy milk'] }">
  <input x-model="title" placeholder="New task">
  <pre x-text="JSON.stringify({ title, tasks }, null, 2)"></pre>
</div>

The <pre> block shows the component's data and updates as you type. In the browser console, Alpine.$data(element) gives the same. There are also browser extensions, such as Alpine.js devtools, that show the component tree.

Common mistake

Adding x-cloak but forgetting the CSS rule. The attribute alone hides nothing — it is a plain attribute that Alpine removes on start. Without the [x-cloak] { display: none !important; } rule the flicker stays. If the rule is there but the element never appears, check that Alpine started at all: most likely the script did not load.

Thanks for reading!

Donate to the site — we work hard for you.