Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

How to Make Livewire Search Filters Shareable with URL Query Parameters

On a Livewire search page, component properties store the current filter choices, such as search text, category, and sort order. A URL query parameter is a value added to an address after ?, such as ?q=laravel&sort=oldest. Binding filter properties to those parameters lets visitors bookmark or share their results. When someone opens the link, Livewire restores the same filter choices.

In Livewire, add the #[Url] attribute to each filter property you want to keep in sync with the URL. When the page loads, Livewire reads the query-string values, which are the values after ? in the address. Livewire updates the URL as the properties change. Use except to leave default values out of the URL. Reset pagination when a filter changes so the visitor does not stay on a page number that the filtered results do not have. Livewire explains these options in its URL query parameter documentation.

Bind filter properties to the URL

Add #[Url] to each property that should be shareable. This example uses a search term, category, and sort order:

use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

class PostSearch extends Component
{
    use WithPagination;

    #[Url(as: 'q', except: '')]
    public string $search = '';

    #[Url(except: '')]
    public string $category = '';

    #[Url(except: 'newest')]
    public string $sort = 'newest';

    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    public function updatedCategory(): void
    {
        $this->resetPage();
    }

    public function updatedSort(): void
    {
        $this->resetPage();
    }

    public function render()
    {
        $query = Post::query();

        if ($this->search !== '') {
            $query->where('title', 'like', '%' . $this->search . '%');
        }

        if ($this->category !== '') {
            $query->where('category_slug', $this->category);
        }

        if ($this->sort === 'oldest') {
            $query->orderBy('published_at');
        } else {
            $query->orderByDesc('published_at');
        }

        return view('livewire.post-search', [
            'posts' => $query->paginate(15),
        ]);
    }
}

The as: 'q' option uses the shorter URL name q for the search property. The except option leaves a property’s default value out of the URL. For example, a visitor who has not chosen a category or changed the sort order gets no parameters for those filters. A filtered URL might look like /posts?q=laravel&category=guides&sort=oldest.

The pagination hooks call resetPage() after a filter changes. Without this call, a visitor on a later results page could change a filter and see an empty page because the filtered results have fewer pages. Change the model, database fields, and page size in the example to match your code.

Bind the properties to inputs in the Livewire view:

<input type="search" wire:model.live="search" placeholder="Search posts">

<select wire:model.live="category">
    <option value="">All categories</option>
    <option value="guides">Guides</option>
    <option value="news">News</option>
</select>

<select wire:model.live="sort">
    <option value="newest">Newest first</option>
    <option value="oldest">Oldest first</option>
</select>

The URL properties hold the component’s filter choices, so a visitor who opens a shared URL sees the same selections and results, based on the data available when the page loads. Treat query-string values as user input. For example, limit sorting to supported options instead of inserting a URL value directly into an SQL column name.

Choose how the URL handles empty values and browser history

Use except to leave a default value out of the URL. Use keep: true to leave a parameter in the URL even when its value is empty. A page may need to keep the parameter for a particular integration or link format. A property that allows null also makes an empty query value such as ?q= resolve to null, as described in the Livewire URL attribute options.

Livewire’s default history behavior updates the URL without adding a browser history entry for every change. Set history: true to let the Back and Forward buttons move through earlier filter states. This option uses history.pushState, a browser feature that adds a history entry. When a search input updates on every keystroke, it adds many entries. Use this option when visitors need to move through each filter state.

If a filter’s URL settings depend on conditions at runtime, you can define its query-string behavior in a queryString() method. Use this method when you cannot set the attribute options on the property declaration. See the query-string configuration options.

Keep filter URLs predictable

Query parameters work well for optional filters because each filter can appear on its own. Use a route path to identify a resource or show its place in a hierarchy. Use query parameters for choices such as search text, category, and sort order. The #[Url] attribute manages query parameters; it does not turn a route parameter into part of the path.

Put only filter choices that should survive a reload or be shared in the query string. Short names such as q make URLs shorter, and except keeps default selections out of the address. If many filters make the URL long, choose which ones need to be shareable instead of including every temporary control.

Livewire versions can handle edge cases differently. A Livewire v3 discussion about empty inputs reports unexpected behavior with empty values under particular keep and history settings. If an empty filter produces an unexpected URL value such as null, check how the Livewire version your project uses handles it. Test the exact attribute options in your code.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *