Jannie Theunissen
Jannie Theunissen

Reputation: 30164

How to set up Alpine.js 3 with mix

I am having trouble getting started with Alpine.js v3 in a new project. This is my package.json and Alpine setup:

  "devDependencies": {
    "laravel-mix": "^6.0.19"
  },
  "dependencies": {
    "alpinejs": "^3.0.6"
  }
import Alpine from 'alpinejs'

window.Alpine = Alpine
window.Alpine.start()

Alpine.data('demo', () => ({
    open: false,

    toggle() {
        this.open = !this.open
    }
}))

driving this markup:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Demo</title>
    <script src="assets/app.js"></script>
  </head>
  <body>
    <div x-data="demo">
      <button @click="toggle">Expand</button>

      <div x-show="open">Content...</div>
    </div>
  </body>
</html>

and I build my javascript using laravel-mix:

// webpack.mix.js

let mix = require('laravel-mix');

mix
    .setPublicPath('public')
    .js('src/app.js', 'public/assets');

The javascript build fine and the page loads without errors, but when I click the toggle button, the content expands as expected, but I get the following error in the browser console and the content won't hide on subsequent clicks.

Uncaught (in promise) TypeError: i is not a function app.js:2282:28

If I defer my script or move it to the bottom, the page is broken on load and I get the following:

Uncaught TypeError: undefined is not a non-null object app.js:1995:12

Can anyone help me fix my setup?

Upvotes: 3

Views: 7132

Answers (1)

Ihar Aliakseyenka
Ihar Aliakseyenka

Reputation: 14193

Most likely you just forget to add defer attribute to script tag

<script defer src="assets/app.js"></script>

But also as documentation says

If you imported Alpine into a bundle, you have to make sure you are registering any extension code IN BETWEEN when you import the Alpine global object, and when you initialize Alpine by calling Alpine.start().

So change your script to

import Alpine from 'alpinejs';

Alpine.data('demo', () => ({
    open: false,

    toggle() {
        this.open = !this.open
    }
}));

window.Alpine = Alpine;

// should be last
Alpine.start();

Note: if there are some errors like assignment to undeclared variable data you may change your import to import Alpine from 'alpinejs/dist/module.cjs';

Upvotes: 7

Related Questions