From 9fb7efd7b8928886e1c60e3cc818d93459ad2399 Mon Sep 17 00:00:00 2001 From: Laurin Stapf Date: Fri, 30 Jan 2026 18:59:31 +0100 Subject: [PATCH 1/3] gitignore: Add composer lock --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6a2315d..571ccff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vendor .idea .DS_Store +composer.lock \ No newline at end of file From 015518426350fec3d129156872f8279f93e8598a Mon Sep 17 00:00:00 2001 From: Laurin Stapf Date: Fri, 30 Jan 2026 20:14:12 +0100 Subject: [PATCH 2/3] wip --- routes/api.php | 3 +++ src/Http/Controllers/InjectController.php | 24 +++++++++++++++++++++++ src/WireExtender.php | 11 ++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/Http/Controllers/InjectController.php diff --git a/routes/api.php b/routes/api.php index bae500f..6fad638 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,5 +1,8 @@ url(app(FrontendAssets::class)->javaScriptRoute->uri), + 'update' => url(app('livewire')->getUpdateUri()), + ]; + } + + public static function middleware() + { + return config('wire-extender.middlewares', []); + } +} \ No newline at end of file diff --git a/src/WireExtender.php b/src/WireExtender.php index 66526cc..7860bc0 100644 --- a/src/WireExtender.php +++ b/src/WireExtender.php @@ -12,7 +12,7 @@ class WireExtender public static function isEmbeddable($component): bool { try { - $reflectionClass = new ReflectionClass(app(ComponentRegistry::class)->new($component)); + $reflectionClass = new ReflectionClass($this->resolveComponentClass($component)); $embedAttribute = $reflectionClass->getAttributes(Embeddable::class)[0] ?? null; return is_null($embedAttribute) === false; @@ -22,4 +22,13 @@ public static function isEmbeddable($component): bool return true; } + + protected function resolveComponentClass(string $component): string + { + if (class_exists(ComponentRegistry::class)) { + return app(ComponentRegistry::class)->getClass($component); + } + + return app('livewire.finder')->resolveClassComponentClassName($component); + } } From e0bdc250fd5a4442a192f7f1b0003785c364e608 Mon Sep 17 00:00:00 2001 From: Laurin Stapf Date: Wed, 4 Feb 2026 17:47:11 +0100 Subject: [PATCH 3/3] Add livewire v4 support --- composer.json | 4 +- js/wire-extender.js | 53 ++++++++++------------- routes/api.php | 4 +- src/Http/Controllers/EmbedController.php | 1 + src/Http/Controllers/InjectController.php | 24 ---------- 5 files changed, 28 insertions(+), 58 deletions(-) delete mode 100644 src/Http/Controllers/InjectController.php diff --git a/composer.json b/composer.json index 9e70311..5163002 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "Embed your Livewire components anywhere.", "require": { "php": "^8.1", - "livewire/livewire": "^v3.4.7" + "livewire/livewire": "^3.4.7|^4.0" }, "license": "MIT", "autoload": { @@ -26,4 +26,4 @@ }, "minimum-stability": "dev", "prefer-stable": true -} +} \ No newline at end of file diff --git a/js/wire-extender.js b/js/wire-extender.js index a4cc1ca..65fe76a 100644 --- a/js/wire-extender.js +++ b/js/wire-extender.js @@ -3,8 +3,7 @@ let componentAssets; let currentScript = document.currentScript; let livewireStarted = false; -function getUri(append = '') -{ +function getUri(append = '') { let uri = document.querySelector('[data-uri]')?.getAttribute('data-uri'); if (!uri) { @@ -18,26 +17,14 @@ function getUri(append = '') return uri + append; } -function getLivewireAssetUri() -{ - return document.querySelector('[data-livewire-asset-uri]')?.getAttribute('data-livewire-asset-uri') ?? getUri('livewire/livewire.min.js'); -} - -function getLivewireUpdateUri() -{ - return document.querySelector('[data-update-uri]')?.getAttribute('data-update-uri') ?? getUri('livewire/update'); -} - -function getEmbedUri() -{ +function getEmbedUri() { const base = document.querySelector('[data-embed-uri]')?.getAttribute('data-embed-uri') ?? getUri('livewire/embed'); const queryString = window.location.search; return base + queryString; } -function injectLivewire() -{ +function injectLivewire(script) { if (window.Livewire || livewireStarted) { return; } @@ -46,10 +33,20 @@ function injectLivewire() style.innerHTML = '[wire\\:loading][wire\\:loading], [wire\\:loading\\.delay][wire\\:loading\\.delay], [wire\\:loading\\.inline-block][wire\\:loading\\.inline-block], [wire\\:loading\\.inline][wire\\:loading\\.inline], [wire\\:loading\\.block][wire\\:loading\\.block], [wire\\:loading\\.flex][wire\\:loading\\.flex], [wire\\:loading\\.table][wire\\:loading\\.table], [wire\\:loading\\.grid][wire\\:loading\\.grid], [wire\\:loading\\.inline-flex][wire\\:loading\\.inline-flex] {display: none;}[wire\\:loading\\.delay\\.none][wire\\:loading\\.delay\\.none], [wire\\:loading\\.delay\\.shortest][wire\\:loading\\.delay\\.shortest], [wire\\:loading\\.delay\\.shorter][wire\\:loading\\.delay\\.shorter], [wire\\:loading\\.delay\\.short][wire\\:loading\\.delay\\.short], [wire\\:loading\\.delay\\.default][wire\\:loading\\.delay\\.default], [wire\\:loading\\.delay\\.long][wire\\:loading\\.delay\\.long], [wire\\:loading\\.delay\\.longer][wire\\:loading\\.delay\\.longer], [wire\\:loading\\.delay\\.longest][wire\\:loading\\.delay\\.longest] {display: none;}[wire\\:offline][wire\\:offline] {display: none;}[wire\\:dirty]:not(textarea):not(input):not(select) {display: none;}:root {--livewire-progress-bar-color: #2299dd;}[x-cloak] {display: none !important;}'; document.head.appendChild(style); + const temp = document.createElement('div'); + temp.innerHTML = script.trim(); + + const scriptEl = temp.querySelector('script'); + livewireScript = document.createElement('script'); - livewireScript.src = getLivewireAssetUri(); - livewireScript.dataset.csrf = ''; - livewireScript.dataset.updateUri = getLivewireUpdateUri(); + livewireScript.src = scriptEl.src; + + for (let attr of scriptEl.attributes) { + if (attr.name.startsWith('data-')) { + livewireScript.setAttribute(attr.name, attr.value); + } + } + document.body.appendChild(livewireScript); } @@ -58,7 +55,7 @@ function waitForLivewireAndStart() { return; } - if(window.Livewire) { + if (window.Livewire) { startLivewire(); } livewireScript.onload = async function () { @@ -68,20 +65,16 @@ function waitForLivewireAndStart() { livewireStarted = true; } -async function startLivewire(assets) -{ +async function startLivewire(assets) { Livewire.hook('request', ({ options }) => { options.headers['X-Wire-Extender'] = ''; options.credentials = 'include'; }) - await Livewire.triggerAsync('payload.intercept', {assets: componentAssets}); + await Livewire.triggerAsync('payload.intercept', { assets: componentAssets }); Livewire.start(); } -function renderComponents(components) -{ - injectLivewire(); - +function renderComponents(components) { fetch(getEmbedUri(), { method: 'POST', headers: { @@ -90,7 +83,7 @@ function renderComponents(components) body: JSON.stringify({ components: components }), - 'credentials': 'include' + 'credentials': 'include' }) .then(response => response.json()) .then(data => { @@ -100,11 +93,13 @@ function renderComponents(components) } componentAssets = data.assets; + + injectLivewire(data.script); waitForLivewireAndStart(); }); } -document.addEventListener('DOMContentLoaded', function() { +document.addEventListener('DOMContentLoaded', function () { let components = []; document.querySelectorAll('livewire').forEach((el) => { diff --git a/routes/api.php b/routes/api.php index 6fad638..c315976 100644 --- a/routes/api.php +++ b/routes/api.php @@ -3,6 +3,4 @@ use WireElements\WireExtender\Http\Controllers\EmbedController; use WireElements\WireExtender\Http\Controllers\InjectController; -Route::any('livewire/embed', EmbedController::class); - -Route::any('livewire/inject', InjectController::class); +Route::any('livewire/embed', EmbedController::class); \ No newline at end of file diff --git a/src/Http/Controllers/EmbedController.php b/src/Http/Controllers/EmbedController.php index 892faec..95ff7f1 100644 --- a/src/Http/Controllers/EmbedController.php +++ b/src/Http/Controllers/EmbedController.php @@ -33,6 +33,7 @@ public function __invoke(Request $request) return [ 'components' => $components, 'assets' => SupportScriptsAndAssets::getAssets(), + 'script' => Blade::render('@livewireScripts'), ]; } diff --git a/src/Http/Controllers/InjectController.php b/src/Http/Controllers/InjectController.php deleted file mode 100644 index 15737b6..0000000 --- a/src/Http/Controllers/InjectController.php +++ /dev/null @@ -1,24 +0,0 @@ - url(app(FrontendAssets::class)->javaScriptRoute->uri), - 'update' => url(app('livewire')->getUpdateUri()), - ]; - } - - public static function middleware() - { - return config('wire-extender.middlewares', []); - } -} \ No newline at end of file