liberusoftware/currency-context-livewire
A Livewire component for the liberusoftware/currency-context package that lets users view and switch the active display currency in your Laravel app. It keeps currency state reactive across Livewire components and offers a simple, framework-friendly API for building currency-aware interfaces.
This package is a presentation adapter, not a currency engine. It assumes a domain module (almost certainly liberusoftware/currency-context) already resolves which currency is active; the Livewire package only exposes that context to the UI — a switcher component, formatted money output, and events when the context changes. Read the domain package first if you want to understand resolution order (session → user preference → tenant → default).
Minimum steps
composer require liberusoftware/currency-context-livewire
php artisan vendor:publish --tag=currency-context-livewire-config # tag name may differ; check the provider
php artisan vendor:publish --tag=currency-context-livewire-views
Before publishing anything, open the package source and answer three questions:
composer.json → what does it require? That tells you the domain package and the minimum Livewire major version. This matters enormously — Livewire 2 and 3 event syntax are incompatible.src/Providers/*.php → find the Livewire::component(...) calls. Those aliases are what you actually type in Blade, and they are not always predictable from the package name.config/ → is there a default currency, a formatter driver, a session key, or a cache TTL? Note the session key; you will need it in tests.First use case: put the switcher in your app layout header, next to the user menu, and confirm that a currency change propagates to a price on the page without a full reload. That single loop exercises config, the service provider, event dispatch, and hydration — if it works, the rest of the package almost certainly works.
{{-- resources/views/layouts/app.blade.php --}}
<header>
@livewire('currency-context.switcher') {{-- verify alias in the service provider --}}
</header>
1. Layout-level switcher with event fan-out. The adapter's job is to mutate the context and announce it. Every money-displaying component should be a listener rather than polling or reading the session during render:
use Livewire\Attributes\On;
use Livewire\Component;
class CartTotals extends Component
{
public array $lines = [];
#[On('currency-context-changed')] // confirm exact event name in the package source
public function refresh(): void
{
// no-op is often enough; re-render re-reads the context
}
public function render()
{
return view('livewire.cart-totals', [
'total' => app(\Liberusoftware\CurrencyContext\CurrencyContext::class)->format($this->rawTotal()),
]);
}
}
2. Never store the currency in your component state. The context lives server-side (session/user/tenant). Cache it in a public property and you get stale prices after a switch, or two tabs disagreeing. Read it from the container at render time.
3. Freeze currency at transaction boundaries. For quotes, orders, and invoices, capture the currency code and the formatted snapshot at creation. A cart that re-formats on context change is correct; a paid invoice that re-formats is a bug and an audit finding.
4. Use the adapter for display only. Formatting belongs here; conversion belongs in the domain layer. If you catch yourself multiplying by a rate inside a Blade view, you have put the exchange-rate concern in the wrong layer — and the adapter will not help you test it.
5. Non-Livewire pages still need the context. If you have plain controllers rendering Blade, check whether the package ships a middleware or a view composer. If not, share it yourself:
View::composer('*', fn ($view) => $view->with(
'currency', app(\Liberusoftware\CurrencyContext\CurrencyContext::class)
));
6. Test isolation. Reset the context in setUp() or a base test case — leaked session state between tests produces the most confusing failures in this kind of package:
Livewire::test('currency-context.switcher')
->call('setCurrency', 'EUR')
->assertDispatched('currency-context-changed');
$this->assertSame('EUR', session('currency'));
dispatch( and copy the string exactly; then grep your own codebase to make sure every money component listens.$listeners arrays versus #[On] attributes, and $emit vs $dispatch. If the package's composer.json allows both majors, pin the one you actually run, and check which API the shipped components use — mixing them fails at runtime, not at install.wire:key on listed money rows. When a parent re-renders on currency change, Livewire's DOM diffing can leave stale formatted strings in keyed lists. Give each row a key that includes the currency code if you see values that "stick".USD in de_DE renders differently from de_DE's default. Make sure the adapter is passing both, and confirm ext-intl is installed — the NumberFormatter fallback path is where most surprises hide.BroadcastChannel in Alpine if it matters for your app.php artisan config:clear before debugging. A stale cached config is a very common red herring here.NOASSERTION license, and a release date in the future. Treat this as internal code you happen to consume: vendor it, pin the exact commit, and read the service provider before you build on it. If the license terms are unclear, do not ship it commercially without clarification — NOASSERTION means the tooling could not identify a recognized license, not that there is none.How can I help you explore Laravel packages today?