livewire: Cannot find Livewire component inside Alpine template

Description

When rendering a Livewire component inside an Alpine <template>, the Livewire component instance cannot be found e.g. when using @entangle() or $wire.entangle().

Exact steps to reproduce

Copy the example below and see the following error in the console:

  • Chrome: Uncaught TypeError: Cannot read property '$wire' of undefined
  • Firefox: Uncaught TypeError: wireEl.__livewire is undefined
  • Safari: TypeError: undefined is not an object (evaluating 'wireEl.__livewire.$wire')

Stripped-down, copy-pastable code snippets

routes/web.php

Route::view('/foo', 'foo');

resources/views/foo.blade.php

<!DOCTYPE html>
<html>
  <head>
    <livewire:styles />
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
  </head>
  <body>
    <div x-data="">
      <template x-if="true">
        <livewire:foo />
      </template>
    </div>
    <livewire:scripts />
  </body>
</html>

app/Http/Livewire/Foo.php

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Foo extends Component
{
    public bool $foo = true;
}

views/livewire/foo.blade.php

<div x-data="{ foo: $wire.entangle('foo') }"></div>

Context

  • Livewire version: 2.2.9
  • Laravel version: 8.9.0
  • Browser: Chrome, Firefox & Safari

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (8 by maintainers)

Most upvoted comments

I was able to reproduce this, but now I’m wondering if it’s a bug or just a limitation of how x-if and x-for work within Alpine?

Guessing here (because I don’t know enough about Alpine under the hood), but doesn’t x-if remove the element from the main DOM? Somehow it seems that this removes the contents of <template> from the scope where the $wire variable is. Perhaps Caleb or one of the dudes who are more familiar with Alpine could shed some light on this.

@zepfietje Does the error still occur if you use the @entangle directive instead of $wire.entangle?

Seems like the directive is the recommended way of using entangle.