Skip to content
LARAVEL 10 · 11 · 12 · 13

Advanced filters, without building the UI.

Declare filters once on an Eloquent model. Render them with Blade, Livewire, Inertia or nothing at all — one backend definition, no duplicated logic.

$composer require laratribe/laravel-advanced-filters
🪞

Self-describing

The server publishes which columns exist, which operators each allows, their labels and how many values they take. That is what makes a generic panel possible — the UI never hardcodes your schema.

🎛️

Four frontends, one backend

Blade + Alpine with no build step, Livewire 3 and 4, Inertia with Vue or React, or no UI at all as a JSON API for a SPA or mobile client.

🧩

Extensible where it counts

Add filter types with their own input views, and operators carrying their own labels and value shapes. Registering adds, publishing overrides — you never fork a shipped view.

🔒

Safe by construction

filters() is the allow-list. A column you did not declare, or an operator a field does not allow, is dropped before it reaches SQL — on every frontend, without extra validation.

01

Declare

Add the trait and a filters() method to the model. This is also the allow-list.

app/Models/Product.php
namespace App\Models;

use Laratribe\AdvancedFilters\Concerns\HasFilters;
use Laratribe\AdvancedFilters\Contracts\Filterable;

class Product extends Model implements Filterable
{
    use HasFilters;

    public static function filters(): array
    {
        return [
            TextFilter::make('name'),
            SetFilter::make('status'),
        ];
    }
}
02

Apply

One scope, on any query, beside your own constraints — then hand the definitions to the view.

app/Http/Controllers/ProductController.php
$filters = $request->input('column_filters');

$products = Product::query()
    ->applyFilters($filters)
    ->paginate(25);

return view('products.index', [
    'products' => $products,
    'fields' => Product::filterDefinitions(),
    'active' => Product::normalizeFilters($filters),
]);
03

Render

The packaged panel, or your own against the wire contract.

resources/views/products/index.blade.php
{{-- Blade + Alpine --}}
<x-advanced-filters::panel
    :fields="$fields"
    :active="$active"
/>

{{ $products->links() }}

Three steps to a working filter UI.

No build step required, and nothing to publish unless you want to restyle it.

Released under the MIT License.