Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Wire Extender Laravel Package

wire-elements/wire-extender

Wire Extender lets you render Livewire components anywhere, even outside your Laravel app. Expose components through a secure API endpoint and mount them on external sites or separate services with the JavaScript client, keeping full interactivity without duplicating code.

View on GitHub
Deep Wiki
Context7

Getting Started

Wire Extender lets you render Livewire components on pages that live outside your Laravel app (marketing sites, WordPress, static HTML, a separate SPA domain) by exposing a small embed endpoint and a JS bundle.

  1. composer require wire-elements/wire-extender
  2. Publish the config: php artisan vendor:publish --tag=wire-extender-config
  3. Set APP_URL correctly — the generated embed script and asset URLs are derived from it, so a wrong value silently breaks every embed in production.
  4. On the external page, drop in the embed script and point a placeholder at a component:
<div wire-extender="counter" :count="5"></div>
<script src="https://your-app.test/wire-extender/wire-extender.js"></script>

First use case: a single interactive island (contact form, pricing toggle, counter) on a site you don't want to rebuild in Laravel. Verify it end-to-end locally before worrying about CORS or auth — those are the two things that will bite you next.

Implementation Patterns

Props from the host page. Pass initial state through attributes on the placeholder element rather than baking values into the component. This keeps the component reusable across multiple host pages and lets non-Laravel authors wire it up without touching PHP.

Multiple islands per page. Each placeholder mounts independently; components keep their own state and round-trips. Good for landing pages with several small widgets. Avoid mounting a single giant component — you lose the benefit and pay the full snapshot payload on first paint.

Protected components. Put auth middleware in the package config so the embed endpoint respects your guard. This is the clean way to ship a "logged-in only" widget that renders on an external dashboard without leaking data — the endpoint checks the session, the JS just fails to mount for guests.

Cross-origin by allowlist. Configure allowed origins explicitly per environment (staging host, production host, local dev port). Do not wildcard this in production; the embed endpoint is a public entrypoint into your app's component tree.

Pair with Livewire conventions. Everything you already do inside Livewire — #[Locked] on IDs, authorize() in mount(), validation rules on public properties — still applies. The external page is untrusted input, treat every prop the same way you'd treat a query string.

Version-locked pairing. Wire Extender's major version tracks Livewire's. v2.x targets Livewire v4; the v2.0.4 release explicitly drops Livewire v3 support. Treat the two packages as a single upgrade unit in composer.json and in your CI matrix.

Gotchas and Tips

Livewire v3 users must stay on 1.x. v2.0.4 removes Livewire v3 support from the 2.x line. If you're mid-migration on Livewire v3, pin wire-elements/wire-extender:^1.0 — otherwise the upgrade will resolve and then break at runtime when the component hydration contract no longer matches.

APP_URL and asset hosts. The embed script and Livewire's own assets are served from your Laravel host. Behind a proxy or on a multi-domain setup, set ASSET_URL / trusted proxies deliberately or embedded pages will request the wrong origin and fail with opaque 404s.

Route caching. The embed and API routes are registered by the package. If you route:cache in deploy, re-run it after config changes — stale route caches after toggling the feature on are a common "it works locally" failure.

CORS is the first thing to check on a blank widget. Open devtools, look at the network tab for the embed request. A blocked preflight looks identical to a component that never mounted. Confirm the requesting origin is in your allowlist, including scheme and port.

Sessions and cookies across domains. If the embedded component relies on auth, the browser needs to send cookies cross-site. That means SameSite=None; Secure on the session cookie plus a matching session domain — a config change on the Laravel side, not the package side.

Debugging mounts. Failed hydration produces a mostly silent failure in the browser. Temporarily point the embed at a trivial component with a single public property to isolate whether the problem is the transport (CORS/URLs/routes) or your component's mount().

Extension points worth knowing. The published config controls the route prefixes, middleware stack, and origin allowlist — that middleware array is where you'll add rate limiting or a tenancy resolver for multi-tenant embeds. Keep those changes in config rather than editing published routes.

Payload visibility. Props passed to the placeholder are visible in the page source, and the Livewire snapshot is too. Never pass secrets, and make sure anything sensitive is re-derived server-side in mount() rather than trusted from the attribute.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager