Phoenix modal does not work with Alpine.js

Hi there!

I tried to use the Modal component from the generated CoreComponents file, but it does not work with Alpine.js.

app.js:

import Alpine from "../vendor/alpine"

window.Alpine = Alpine
Alpine.start()

let liveSocket = new LiveSocket("/live", Socket, {
  params: {_csrf_token: csrfToken},
  dom: {
    onBeforeElUpdated(from, to) {
      if (from._x_dataStack) {
        window.Alpine.clone(from, to)
      }
    }
  }
})

html:

<.modal id="test-modal" show>
  MODAL
</.modal>

If I remove Alpine.start() the modal works fine. Does anyone know why this component does not work with Alpine.js? Is there something wrong with my setup?

Thank you in advance!

Is the show here a typo?

No, it is the same as show={true}. The component expects this attribute to determine whether to show the modal or not.

Is your browser console showing any errors? Did you assign a value to csrfToken before creating the LiveSocket?

EDIT: I just tested it with your LiveSocket config and it worked fine. Here’s the csrfToken declaration if you don’t have one:

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");

How did you install Alpine.js? What version are you using?

Yes, I assign a value to csrfToken before creating the socket.

OK, I think I have your answer: You probably have the wrong build of AlpineJS installed. Download the ESM module into assets/vendor/alpinejs.js (you need the file called module.esm.js, not cdn.js). Here’s a link to a minified version of this module: https://cdn.jsdelivr.net/npm/alpinejs@^3.0.0/dist/module.esm.min.js

My Workflow (npm)

I have an npm project in the assets/ directory (cd assets && npm init -y), run npm install alpinejs, then import it in app.js: import Alpine from "alpinejs";.

I just did the above with the newest versions of everything (Phoenix v1.7.6 | LiveView v0.19.3 | AlpineJS 3.12.3) and the modal worked as expected, even with a couple Alpine components inside and outside of it for good measure.

Getting it working without npm

First, I tried downloading alpinejs (the actual file was called cdn.js) into assets/vendor/alpinejs.js and importing it as you described. This produced an error in the browser console: Uncaught TypeError: import_alpinejs.default.start is not a function. (Also, Alpine didn’t work with or without the <.modal> component.)

I Googled the error, which led to this Elixir Forum post. In there, the ever-helpful @NobbZ explained that the user (and me, and probably you) had installed the regular version of AlpineJS (The one that should be run via a <script> tag), but you can’t import that version the way we are trying to do: You need the ESM module.

So I downloaded the ESM module (the file is called module.esm.js) into assets/vendor/alpinejs.js, and then everything worked.

So hopefully that does the trick!

2 Likes

Thank you so much! It fixed it.