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.
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>
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<?php2 3return [4 'paths' => ['livewire/*'],5 6 // ...7];
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 Component10{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>
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@assets10<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@endassets13 14@script15<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.
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 🎉