Visitors filling an address field is time-consuming and prone to errors, especially when your app requires valid coordinates to display a map or filter results by location.
A user might spend thirty seconds typing out "123 Main Street, San Francisco, CA 94102" character by character. They hit submit, and then realize they made a typo. Or worse, they entered an address that doesn't exist. Your app processes it, shows a broken map, and the user leaves frustrated.
You could ask for their current location via the browser. But most users won't grant that permission. At least I don't, because I don't trust how my location data gets handled. Plus, a user's current address isn't always their billing address.
A better way: autocomplete powered by a location service.
Mapbox provides a geocoding API that returns validated addresses as you type. You get a full address plus latitude and longitude coordinates, all in one response. Perfect for maps, geo-filters, or anything else you need.
The typical implementation uses Mapbox's JavaScript SDK. But it forces their UI library on your users. You lose control over how suggestions display, and you load an extra frontend dependency. I prefer to rely on my backend as much as possible. Even for frontend features.
Here's the approach I built: Mapbox API combined with Flux UI's select component and backend search. It's clean, minimal, and gives you full control over the UX.
Here's how it works. A user starts typing an address. After three characters, Livewire calls your backend. The backend hits Mapbox's geocoding API with the search query. Mapbox returns up to 10 autocomplete suggestions with full addresses and coordinates. Flux UI displays these as options. When a user selects one, you store the address, latitude, and longitude. No frontend Mapbox SDK, no extra bloat, just clean backend-powered autocomplete.
The backend is straightforward. Here's the method that calls Mapbox's API and extracts what we need:
private function searchMapbox(): void { $response = Http::get('https://api.mapbox.com/search/geocode/v6/forward', [ 'q' => $this->searchQuery, 'access_token' => config('services.mapbox.access_token'), 'limit' => 10, 'autocomplete' => 'true', ]); $data = $response->json(); $this->suggestions = collect($data['features'] ?? []) ->map(fn ($feature) => [ 'id' => $feature['id'], 'full_address' => $feature['properties']['full_address'], 'longitude' => $feature['geometry']['coordinates'][0], 'latitude' => $feature['geometry']['coordinates'][1], ]) ->toArray(); }
On the frontend, Flux UI's combobox makes this simple:
<flux:select wire:model="selectedAddressId" variant="combobox" :filter="false" placeholder="Search for an address..." > <x-slot name="input"> <flux:select.input wire:model.live="searchQuery" /> </x-slot> @foreach ($suggestions as $suggestion) <flux:select.option value="{{ $suggestion['id'] }}"> {{ $suggestion['full_address'] }} </flux:select.option> @endforeach </flux:select>
The key is variant="combobox" with :filter="false". This tells Flux to skip client-side filtering and let the server handle it. The search query updates via wire:model.live, triggering the backend call. When a user selects an option, you get the full address plus coordinates.
This approach solves the address problem without adding complexity. You get valid addresses guaranteed. Mapbox validates everything before it reaches your app. Latitude and longitude come with every selected address, no separate geocoding step needed. Users select from suggestions instead of typing manually. You own the presentation layer, not Mapbox. No frontend SDK dependency, minimal client-side code. Suggestions load from your backend, controlled by you.
Your users get a smooth experience. Your app gets reliable address data. And you avoid the bloat of loading another frontend library.
You can see this in action at address-search.antihq.com or explore the full implementation on GitHub at github.com/antihq/address-search. Hope this experiment saves you some time, or inspires you to apply this backend-first approach to other frontend problems.