reachweb/statamic-livewire-filters
Add reactive, Livewire-powered filtering to your Statamic site. Build faceted search and filter interfaces that update instantly without full page reloads, backed by a simple, developer-friendly API. Ideal for collections, entries, and product listings.
Architecture fit
blocked_query_params blocklist, allowed_filters escape hatch, #[Locked] identity properties, protected setParameters(), and rejection of Antlers-evaluated : keys reduce the risk of query-control injection through Statamic parameters such as status, from, site, limit, paginate, filter, since/until, and similar keys.Integration feasibility
filterUpdated(), clearFilter(), and clearFilters() gain an optional $boundsSelection = null parameter; published lf-range.blade.php or lf-dual-range.blade.php views need the range-bounds-updated listener if dynamic bounds are enabled.allowed_filters. For example, if visitors are allowed to change limit, that key must be allowed explicitly.status:is, must remove that key from blocked_query_params or allow it through allowed_filters. This is a plausible edge case for content-heavy sites with custom filter fields.Technical risk
php artisan config:clear or php artisan config:cache must be run after updating; otherwise the new blocklist stays unset and nothing is blocked. This creates a false sense of security if deployment procedures skip config cache refresh.limit or site on the first filter change. This is an operational risk more than a code risk, but it can produce confusing production behavior immediately after release.allowed_filters is configured. This should be treated as a product-behavior change requiring validation, not just a library upgrade.setParameters() protected are positive security changes but may break custom client-side or subclass integrations that depended on mutating those values.filter-updated can affect custom UI logic. If a team previously dispatched filter-updated to force a refresh, they need to call Livewire’s $refresh on the collection instead.Key questions
allowed_filters.status:is or limit? If so, what is the allowlist/blocklist exception strategy?filterUpdated(), clearFilter(), or clearFilters()? Do they need signature updates?clear-all-filters so “Clear all” resets their controls?params-updated with one argument only? They should remain compatible, but the new second argument should be understood.Stack fit
Migration path
php artisan config:clear or php artisan config:cache, and clear Statamic static cache with php please static:clear.blocked_query_params against existing filter fields. If a legitimate filter key is blocked, either remove it from the blocklist or add it to allowed_filters.limit, site, status, or similar keys through the URL, add those keys to allowed_filters along with normal filter keys.$boundsSelection = null parameter on filterUpdated(), clearFilter(), and clearFilters().range-bounds-updated listener or re-publish lf-range.blade.php and lf-dual-range.blade.php.clear-all-filters handling so “Clear all” resets their internal controls as expected.filter-updated solely to force a refresh with Livewire’s $refresh on the collection.Compatibility
params-updated listeners remain compatible; the event now also carries hardened parameters and a second argument for the encrypted bounds query.#[Locked] change on filter identity properties may break custom code that mutated field, condition, modifier, collection, blueprint, or statamic_field from the client side. That is intentional hardening and should be treated as unsupported behavior going forward.setParameters() becoming protected prevents client invocation. Any custom front-end integration calling it directly must be refactored.status also blocks status:is. This is important for teams with colon-namespaced filter keys.allowed_filters now checks each active query scope independently, fixing a prior issue where two active scope filters could drop both scopes. This is a behavior fix, but teams relying on the old behavior should validate scope filtering after upgrade.Sequencing
blocked_query_params exceptions and allowed_filters for any legitimate control keys or colon-namespaced fields.enable_dynamic_range_bounds only after functional and performance validation on representative content sets.Maintenance
blocked_query_params blocklist is populated by default and requires no configuration for standard use. However, teams with custom control-key behavior must maintain allowed_filters and blocklist exceptions deliberately.allowed_filters now checks each active query scope independently, filter configurations with multiple scope filters should be regression-tested and documented.Support
allowed_filters for intentionally client-addressable control keys, and adjust blocked_query_params for fields named like control keys.CHANGELOG.md.clear-all-filters and range-bounds-updated events.Scaling
enable_filter_values_count is on.enable_filter_values_count is off, the count listener does nothing, which avoids unnecessary work.Failure modes
limit or site on first filter change.status:is: filtering can break unless the key is removed from blocked_query_params or allowed through allowed_filters.range-bounds-updated listener: dynamic range bounds may not update the custom UI correctly.clear-all-filters: “Clear all” may clear core filters but leave custom component controls active.setParameters(): will fail because the method is now protected.filter-updated only to force a refresh: no re-render will occur when the event changes nothing; use Livewire $refresh instead.Ramp-up
allowed_filters.preset_value, range slider reset behavior, “Clear all,” custom filter components, and faceted counts.range-bounds-updated event before enabling it for all users.How can I help you explore Laravel packages today?