Alpine.js
Alpine.js is a lightweight, declarative JavaScript framework designed for adding interactive behavior directly into HTML markup, often described as 'Tailwind for JavaScript'. It operates by directly attaching JavaScript behavior to DOM elements via `x-` attributes, avoiding the need for a build step, virtual DOM, or component compilation for many use cases. The current stable version is 3.15.11, with frequent patch and minor releases focusing on bug fixes, performance enhancements, and new directive modifiers. Key differentiators include its minimal bundle size, direct-in-HTML approach, and Vue-like reactivity for small, interactive components, making it ideal for augmenting server-rendered applications or for projects where a full-fledged SPA framework is overkill.
Common errors
-
ReferenceError: Alpine is not defined
cause Alpine.js script was not loaded or imported before it was accessed, or `Alpine.start()` was not called.fixEnsure the Alpine.js script tag is present in your HTML (preferably with `defer`) or that `import Alpine from 'alpinejs'; Alpine.start();` is executed in your JavaScript bundle. -
Alpine Expression Error: Cannot read properties of undefined (reading 'foo')
cause Attempting to access a property `foo` within an Alpine expression (e.g., `x-text="foo"`) where `foo` is not defined in the current component's `x-data` scope or a parent scope.fixVerify that the property `foo` is declared within the `x-data` object of the current element or one of its ancestors. If it's intended to be global, ensure it's registered with `Alpine.data()` or `Alpine.store()`. -
Content Security Policy: The page’s settings blocked the loading of a resource at self ("script-src").cause Your browser's Content Security Policy is preventing Alpine.js from executing dynamic JavaScript, typically due to the lack of `'unsafe-eval'` in the `script-src` directive.fixModify your server's CSP header or HTML meta tag to include `'unsafe-eval'` in `script-src`, e.g., `<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval';">`. Exercise caution with `unsafe-eval`.
Warnings
- breaking Alpine.js v3 introduced significant breaking changes from v2, including changes to the global API (`Alpine.data` vs. `x-data` directly), removal of implicit global state, and changes to magic property definitions. Directives like `x-ref` also behave slightly differently.
- gotcha Content Security Policy (CSP) configurations can block Alpine.js's dynamic expression evaluation if not properly configured. Alpine uses `eval` internally, which might conflict with strict `script-src` policies, potentially leading to errors like 'unsafe-eval' blocked.
- gotcha Reactivity with `x-model` and other directives can sometimes lead to unexpected timing issues, especially when dealing with form submissions or external state mutations. For instance, `x-model.blur` might not have flushed its value before a form's submit handler runs.
- deprecated While `x-init` can still execute statements directly, the recommended pattern for `x-init` in Alpine v3+ is to return a function. This returned function will then be executed after the element is added to the DOM and all child components are initialized, which is crucial for handling asynchronous operations correctly.
Install
-
npm install alpinejs -
yarn add alpinejs -
pnpm add alpinejs
Imports
- Alpine
const Alpine = require('alpinejs');import Alpine from 'alpinejs';
- Alpine plugins
import Focus from '@alpinejs/focus'; import Collapse from '@alpinejs/collapse';
- Alpine types
import type { Alpine } from 'alpinejs';
Quickstart
import Alpine from 'alpinejs';
// Register a global data store or component for use with `x-data="myStore"`
Alpine.data('myCounter', () => ({
count: 0,
message: 'Hello Alpine!',
init() {
// Optional initialization logic
console.log('myCounter component initialized');
},
increment() {
this.count++;
},
decrement() {
this.count--;
}
}));
// Register a global magic property like $myMagic
Alpine.magic('myMagic', el => 'This is a magic string!');
// Start Alpine.js
Alpine.start();
// Typically, Alpine.js is then used in HTML like this:
/*
<div x-data="myCounter">
<h1 x-text="message"></h1>
<p>Count: <span x-text="count"></span></p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<p x-text="$myMagic"></p>
</div>
*/