Embed Livewire Components Using Wire Extender

Embed Livewire Components Using Wire Extender

Wire Extender allows you to embed any Livewire component on any website or even within a static HTML file.

What if you could embed your Livewire component anywhere? An embedded form, an entire chat widget, you name it! All you need is a way to extend your wire. Luckily, you can get Wire Extender to do the heavy lifting for you.

Try the demo

Create a new HTML file on your local machine with the following contents to get a Livewire powered click counter 😎

1<html>
2<head>
3 <script src="https://unpkg.com/@wire-elements/wire-extender" data-uri="https://wire-elements.dev"></script>
4 </head>
5<body>
6 <livewire data-component="counter" data-params='{"count":10}'></livewire>
7</body>
8</html>

Installation

Please be aware that Wire Extender is in development - Pull requests and feedback are welcome 😄 https://github.com/wire-elements/wire-extender

To get started, require the package via Composer:

1composer require wire-elements/wire-extender

Next, open app/Http/Middleware/VerifyCsrfToken.php and add the IgnoreForWireExtender trait:

1<?php
2 
3namespace App\Http\Middleware;
4 
5use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
6use WireElements\WireExtender\Http\Middlewares\IgnoreForWireExtender;
7 
8class VerifyCsrfToken extends Middleware
9{
10 use IgnoreForWireExtender;
11 
12 //...
13}

This trait will disable the CSRF token verification for any embeddable component when the wire-extender client makes a request to the /livewire/update endpoint. Why? Because any embeddable component is stateless and doesn't support session, and therefore CSRF validation will not work.

Finally, we need to adjust our CORS settings to allow cross-origin requests. Open config/cors.php and add livewire/* to the paths array.

1<?php
2 
3return [
4 'paths' => ['livewire/*'],
5 
6 // ...
7];

Creating an embeddable component

You can embed any Livewire component, just add the #[Embeddable] attribute to your component class:

1<?php
2 
3namespace App\Livewire;
4 
5use Livewire\Component;
6use WireElements\WireExtender\Attributes\Embeddable;
7 
8#[Embeddable]
9class Counter extends Component
10{
11 public $count = 0;
12 
13 public function increment()
14 {
15 $this->count++;
16 }
17 
18 public function decrement()
19 {
20 $this->count--;
21 }
22 
23 public function render()
24 {
25 return view('livewire.counter');
26 }
27}
1<div>
2 Count: {{ $count }}
3 
4 <button wire:click="increment">+</button>
5 <button wire:click="decrement">-</button>
6</div>

What about component assets and scripts?

They work out of the box, just use the @assets and @script directives as per Livewire's documentation.

1 
2<div>
3 Count: {{ $count }}
4 
5 <button wire:click="increment">+</button>
6 <button wire:click="decrement">-</button>
7</div>
8 
9@assets
10<script src="https://cdn.jsdelivr.net/npm/pikaday/pikaday.js" defer></script>
11<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/pikaday/css/pikaday.css">
12@endassets
13 
14@script
15<script>
16 new Pikaday({ field: $wire.$el.querySelector('[data-picker]') });
17</script>
18@endscript

If you are using nested components, please make sure all components have the #[Embeddable] trait.

Embedding a component

You are almost ready to embed your component. First, let's make sure we publish the wire-extender.js library by running the vendor:publish artisan command.

1php artisan vendor:publish --tag=wire-extender

Now that the asset is published you can include it on the website where you want to embed your Livewire component:

1<html>
2 <head>
3 <script src="//your-domain.com/vendor/wire-elements/wire-extender.js"></script>
4 </head>
5</html>

By default, it will automatically use the domain hosting the script to load the livewire.js library and to make API calls. If you want, you can override these using data attributes:

1<!-- Set custom `livewire.js` url -->
2<script src="/wire-extender.js" data-livewire-asset-uri="//example.com/livewire.js"></script>
3 
4<!-- Set custom `livewire/update` url -->
5<script src="/wire-extender.js" data-update-uri="//example.com/livewire/update"></script>
6 
7<!-- Set custom `livewire/embed` url -->
8<script src="/wire-extender.js" data-embed-uri="//example.com/livewire/embed"></script>

Please be aware that Livewire either uses livewire.js or livewire.min.js depending on your APP_DEBUG setting. Wire extender will always attempt to load livewire/livewire.min.js. If APP_DEBUG is set to true, you will need to use the data-livewire-asset-uri attribute to override the asset url to livewire/livewire.js

You can also use a CDN if you don't want to publish and host the assets on your own website:

1<script src="//unpkg.com/@wire-elements/wire-extender" data-uri="https://example.com"></script>

All that remains is defining the component(s) you want to embed:

1<livewire data-component="counter" data-params='{"count":10}'>
2 <!-- Placeholder... -->
3</livewire>

While the initial API call is made, you can render a custom placeholder. Typically this only takes a few miliseconds. If you have components that take more time to render, consider using the #[Lazy] attribute provided by Livewire and a public function placeholder() method.

That's it! Your component should now appear 🎉

To navigate
Press Enter to select