The problem: Alpine.js directives like x-data sit silently in your Blade markup, and the console screams Alpine is not defined the moment the page loads.
Environment: Laravel 11, Vite 5, Alpine.js 3.x, Node 20, npm 10
The Error
Uncaught ReferenceError: Alpine is not defined
at HTMLDivElement.eval (welcome.blade.php:12)
at eval (app.js:1)
Why It Happens
This almost always comes down to load order. Alpine.js needs to be initialized before the browser parses any element that uses x-data, x-show, or similar directives. Two common setups cause this:
1. You installed alpinejs via npm but never imported and started it in your resources/js/app.js — so Vite bundles your other JS, but Alpine's global object never gets attached to window.
2. You're using @vite correctly, but your Blade template has inline x-data markup rendered above the @vite directive in your layout, so the DOM element exists before the script that powers it does.
Alpine's CDN build auto-starts itself, but the npm/Vite build does not — you have to call Alpine.start() yourself. Missing that one line is the #1 cause of this error.
The Fix
Open resources/js/app.js and make sure Alpine is imported, attached to window, and started explicitly:
- import './bootstrap';
+ import './bootstrap';
+ import Alpine from 'alpinejs';
+
+ window.Alpine = Alpine;
+ Alpine.start();
Then confirm your main layout loads the compiled script before the closing </body> tag, not in the <head>:
<body>
{{ $slot }}
@vite(['resources/css/app.css', 'resources/js/app.js'])
</body>
Save, then rebuild your assets so Vite picks up the change:
npm run build
Step-by-Step
- Open
resources/js/app.jsand confirmimport Alpine from 'alpinejs'is present. - Add
window.Alpine = Alpine;right after the import. - Call
Alpine.start();as the last line — never before other plugins are registered. - Check your Blade layout: the
@vite(...)directive must sit just before</body>. - Run
npm run dev(ornpm run buildfor production) and hard-refresh the browser (Ctrl+Shift+R) to clear cached JS. - Open DevTools console and confirm the error is gone before testing your
x-datacomponents.
Edge case: If you're using Alpine plugins like @alpinejs/persist or @alpinejs/focus, they must be registered with Alpine.plugin(...) before Alpine.start() is called — not after. Calling start() first will silently ignore the plugin, and you'll get a different but related bug (plugin directives just not working, no console error at all).
Still stuck after checking load order and the build step? Reach out on the Contact page and I'll help you debug it.