Changelog β
v4.6.3 (Nov 4th, 2026) β
Changed
- Filters and
lf-sortread the URL's filter parameters when they mount, so on a filtered URL the page shows ticked checkboxes, selected options and filled inputs straight away, in both URL query string modes. Before, controls rendered empty and filled in after a second Livewire request, and{{ nocache }}regions returned empty controls. Filters set from presets on the{{ livewire-collection }}tag still arrive throughpreset-params, which now only carries filter parameters andsort.
Fixed
- With full-measure static caching,
{{ livewire-filters:head }}waits forDOMContentLoadedbefore starting Livewire, soalpine:initlisteners placed after{{ livewire:scripts }}, such as ones that registerAlpine.store, run in time. See Static Caching. - With
custom_query_stringand full-measure static caching, filter changes no longer sometimes leave the browser URL unchanged. - With
custom_query_stringand{{ nocache }}regions on full measure, a paginated URL such as/cars/search/brand/audi?page=2now opens on that page instead of page 1.
Upgrading
Sites that use the bundled views need no changes. Check these if they apply:
- Custom filter components that relied on
preset-paramsfor a URL parameter no longer receive it. ReadCustomQueryString::urlParams()at mount; filters that use theIsLivewireFiltertrait and definesetPresetValues()get this automatically. - Published filter views keep working but only show the selection once Livewire starts. Copy the new
@checked,@selectedandvalueattributes from the bundled views to show it in the server HTML. - Published
livewire/utility/url-handler.blade.php: re-publish it or merge in the new script to get the URL fix.
v4.6.2 (Nov 4th, 2026) β
Performance
A performance release: faster counts, range bounds and filter options, smaller Livewire responses and fewer Livewire requests. Results, counts and bounds are the same as before.
Requirements
- Statamic 5 sites need 5.29 or later. On an older 5.x,
composer updatekeeps you on 4.6.1, so nothing breaks. Statamic 6 is unchanged. See Requirements.
Changed
- Faceted counts and dynamic range bounds find the matching entries once per filter state per request and read each field straight from the Stache index, instead of running one sorted query per filter. On a 5,000-entry collection with 8 filters, the counts request after page load drops from about 1 s to 300 ms. The Eloquent driver is unchanged.
- Term and entry option labels are read from the Stache indexes instead of loading every term and entry, so filters over a large taxonomy or collection mount several times faster. Option lists are no longer written to the cache store on every page view, so
lw_computedcache files stop piling up. - Filters no longer send HTML the browser throws away, and with
enable_filter_values_countoff their snapshots no longer carry an empty counts array. - Fewer Livewire requests: the bundled checkbox view sends its update to the collection from the browser, the bundled
lf-countview updates from theentries-updatedevent, the collection skips the tags update on page load when there's nothing to show, and "Clear all" only asks a filter to send a change back when it needs to. On the demo site a filtering session makes 8β26% fewer requests and receives up to 27% less data. entries-updatedalso carriesentriesLabel, the translated count text.clear-all-filtersfrom the collection carries two arguments: the condition keys it kept and the parameters it removed. See Clearing All Filters.validate_filter_valuesstill shows an error for an invalid checkbox value, but no longer stops the bundled checkbox view from applying it. Useallowed_filtersandblocked_query_paramsto control which parameters the collection accepts. See Configuration.
Fixed
- With full-measure static caching,
{{ livewire-filters:head }}now starts Livewire even when its script runs after Statamic has replaced the CSRF token. Before, filters could stay unresponsive on slow networks. Place the tag before your stylesheets. See Static Caching. - A selection made while "Clear all" was on its way no longer stays applied after the filter resets.
Upgrading
Sites that use the bundled views, or published copies of them, need no changes. Check these if they apply:
- Custom views that read
$statamic_field['counts']: with counts off the key is no longer set. Use$this->counts[$value], which works with counts on or off. - Subclasses of
LfCheckboxFilterthat definepayload(),updatedSelected()ordispatchFilterUpdated()keep updating through the server and work as before. - Published
lf-checkbox.blade.phporui/count.blade.php: both keep working through the server. Re-publishlf-checkbox.blade.php, or delete a publishedcount.blade.php, to get the saved requests. See Publish the views. - Custom
clear-all-filterslisteners that declare parameters now receive the kept keys and the removed parameters, in that order.
v4.6.1 (Nov 2nd, 2026) β
Security
- Faceted counts now only use the encrypted filter state that the collection sends, the same one dynamic range bounds use. A crafted
params-updatedevent could previously put query controls into the count query and reveal whether matching draft, future or other-site entries exist. - The
viewproperty of every filter component is now#[Locked], so a tampered request can't switch a filter to another view. Settingviewon the tag still works.
Changed
params-updatedalways carries its second argument, the encrypted query, whenenable_filter_values_countorenable_dynamic_range_boundsis on. Custom code that dispatchesparams-updatedto refresh counts must pass it.- The bundled filters now extend a new abstract
LivewireFilterclass. Subclasses of a bundled filter that definepayload(),emptyValue(),applyPreset()ordispatchFilterUpdated()must match the new signatures.
Fixed
- A dual-range filter on a date field no longer crashes after a URL or tag preset, and removing a dual-range tag resets only the bound it names.
- With dynamic range bounds on, "Clear all" keeps range sliders within the full-collection bounds.
- Pretty URLs with several
query_scopealiases now apply every scope. condition="taxonomy"on a field whose handle isn't the taxonomy handle now throws a clear exception at mount.- Faceted counts no longer crash on fields holding nested arrays or objects, and multi-collection and multi-taxonomy counts now match the entries.
- Localized term routes now filter by the default-locale term slug.
Upgrading
- If you published
tags.blade.php, pass$tag['condition']as the third argument ofremoveOption.
v4.6.0 (Oct 21st, 2026) β
Security: query parameter hardening
Livewire keeps the active filter state in a public property, so a crafted request can inject any key into it, including Statamic query controls like from, status, limit and site that change which entries are returned rather than filtering them. This release blocks that by default, with no configuration needed.
New
blocked_query_paramsconfig option: a blocklist of query control keys (status,from,site,limit,paginate,since/until,filter, and more) stripped from filter state sent by the client before the entries query runs. It ships populated, so there is nothing to set up. Parameters set directly on the{{ livewire-collection }}tag are always kept, andallowed_filterscan let a specific key back through (a value sent by the client then overrides the one set on the tag). See Securing parameters.- Dynamic range bounds: set the new
enable_dynamic_range_boundsconfig option totrueand the Range and Dual Range filters narrow their slider to the values that still match the other active filters. A selection the user has made is never moved, and an unused slider is disabled when there's nothing left to choose between. It's off by default, since it runs a query for each range filter after every change. See Dynamic bounds.
Changed
- Removing a filter from the tags, or clicking "Clear all", now updates the collection in a single Livewire round trip instead of waiting for each filter to relay the change back. The
clear-optionandclear-all-filtersevents still reach filter components with the same payloads, so custom filters keep working. On "Clear all", parameters set on the tag or by aninithook are still only cleared by their own filter component, and Resrv's availability filter keeps its dates. - A
filter-updated,clear-filterorclear-optionevent that changes nothing (on page 1) no longer re-renders the collection. If you dispatchedfilter-updatedto force a refresh, call Livewire's$refreshon the collection component instead. - Filter identity properties (
field,condition,modifier,collection,blueprint,statamic_field), and thecollection,blueprintandfieldsproperties of the sort component, are now#[Locked], so a tampered request can no longer change what a filter points at. setParameters()on theLivewireCollectioncomponent is nowprotected. Livewire exposes every public method as an action the client can call, and this one writes trusted state such as the collection andallowed_filters. If you were calling it from custom code, pass the parameters through the tag instead.- Filter state keys starting with
:are rejected. Statamic evaluates a:keyparameter as an Antlers expression, so a crafted request could have one evaluated inside the entries or count query. - Filter state arriving through the URL (
params[...], in both query string modes) is sanitized before it reaches the component: blocked keys are stripped, and parameters that configure the tag itself (from,view,paginate,allowed_filtersand the other collection aliases) are never read from the URL, since they can only be set on the tag. If you relied on a URLlimitwith legacypaginate="true"pagination, allow it back withallowed_filters(for exampleallowed_filters="transmission:is|limit"). - Query control parameters written by a server
inithook keep working: anything the hook adds, changes or removes during mount is treated as trusted, the same as parameters set on the tag, since hooks are registered in your own application code. - Counts are calculated from the same hardened parameters as the entries query, so the blocklist and
allowed_filtersapply to them too, and the first counts on page load include parameters added byinithooks. - The
params-updatedevent carries the hardened parameters instead of the raw filter state, gains a second argument (the encrypted bounds query) and also fires when only dynamic bounds are on. Listeners that take one argument keep working. - The count listener now exits early when
enable_filter_values_countis off, so no queries run when the feature is disabled, and it always counts within the filter's own collection.
Fixed
- Moving a range slider back to its default value now clears the filter instead of leaving it in the URL and the tags.
- Toggle filters with a numeric or boolean
preset_valuenow show as on when restored from the URL or a preset. - Removing a tag for a condition, taxonomy or query scope parameter that has no filter component on the page now removes it. Previously the click did nothing.
- With
allowed_filters, an active query scope is now allowed when its ownquery_scope:<scope>entry is listed. Previously the whole scope list had to match one entry, so two active scope filters dropped both scopes.
Upgrading
- Config cache: If you cache your config, run
php artisan config:clearor rebuild it withphp artisan config:cacheafter updating, otherwise the blocklist stays unset. See Upgrading and the config file. - Published range views: If you published
lf-range.blade.phporlf-dual-range.blade.php, merge in the newrange-bounds-updatedlistener (the range view also reads$dynamicMin,$dynamicMaxand$boundsDisabled) or re-publish them, otherwise the sliders won't update when dynamic bounds are on. See the Range and Dual Range filter pages. - Static caching: clear the static cache after updating (
php please static:clear). Pages cached under 4.5.1 hold the old component state, so on the first filter change control parameters set on the tag (such aslimitorsite) would be stripped as if a visitor had sent them. See Static caching. - Fields named like a control key: a filter on a field whose handle is a blocked key (such as
status,siteorfrom) is now stripped. See Fields named like a control key. - Sensitive query scopes:
query_scopeisn't blocked, since the addon builds it for scope filters. Lock scopes down withquery_scope:<scope>entries inallowed_filters. See Which should I use?. - Custom filter components: "Clear all" now removes every filter parameter except those set on the tag or by an
inithook, including those from custom components that don't listen forclear-all-filters. If such a component should reset its own controls too, listen for that event. - Overridden methods:
filterUpdated()andclearFilter()on theLivewireCollectioncomponent, andclearFilters()on the filter components, have a new optional$boundsSelectionparameter. If you extend one of these components and override any of these methods, add$boundsSelection = nullto its signature, otherwise PHP throws a fatal "must be compatible" error.
π Full guide: https://livewirefilters.com/usage/livewire-collection-tag#securing-parameters
v4.5.1 (Jun 29th, 2026) β
Fixed
-Fix browser-history behavior when using the addon's custom query string mode
v4.5.0 (Jun 19th, 2026) β
New
- Infinite scroll / "Load more" pagination β add
infinite_scroll="true"to the{{ livewire-collection }}tag to enable incremental loading, then render the trigger with the new{{ livewire-filters:load_more }}tag. Useauto="true"for true infinite scroll or omit it for a manual "Load more" button; either way it degrades to a real button without JavaScript. Each load grows the page by the initialpaginatevalue and resets on filter/sort change. The trigger is a publishable partial with translatable labels.
Fixed
- Duplicate browser history entries when paginating in custom query string mode, plus more reliable browser Back button behaviour.
- Static caching on multisite installs: correct site resolution and subdirectory handling.
π Full guide: https://livewirefilters.com/usage/livewire-collection-tag#infinite-scroll-load-more
v4.4.0 (Jun 14th, 2026) β
Static Caching Support
Improves Livewire Filters' support for statically cached pages (full and half measure).
New
{{ livewire-filters:head }}tag β add it to your layout before{{ livewire:scripts }}to prevent 419 "Page Expired" errors on the first filter interaction under full-measure caching. Outputs nothing when caching is off, so it's safe to leave in permanently.- Better
{{ nocache }}handling across all URL modes β filter state is rehydrated on Statamic's/!/nocacherequests, so filters resolve correctly on a shared cache shell in both the Livewire and custom query string modes (no more stale or "poisoned" filtered pages).
Changed
- Query string modes are now mutually exclusive β when
enable_query_string(Livewire) is on,custom_query_stringis ignored.
Fixed
- Taxonomy terms with numeric slugs are no longer dropped from filter options and counts.
π Full guide: https://livewirefilters.com/advanced/static-caching
v4.3.2 (Mar 25th, 2026) β
- Fix counts for custom options array.
v4.3.1 (Mar 24th, 2026) β
- Preserve existing (non-filter) query parameters when rewriting custom filter URLs
- Avoid pushing browser history when the computed URL is unchanged.
v4.3.0 (Mar 20th, 2026) β
- Laravel 13 support
v4.2.0 (Mar 20th, 2026) β
Performance
- Shared count queries β filters with the same base parameters share a single query instead of each running their own.
- Eloquent optimization β on sites using the Eloquent driver, counts pull only the needed field values directly from the database instead of hydrating full entry objects.
- Request-level caching β taxonomy terms, collection entries, dictionary options, and blueprint lookups are cached within the request so duplicate lookups are avoided.
Bug Fixes
- Custom query string URL matching β /myfilters/ no longer incorrectly matches a filters prefix. Matching is now segment-exact.
- Query scope count parameters β fixed incorrect count results when using scoped filters.
- Livewire request detection β now uses the X-Livewire header instead of checking for the livewire/update path, fixing issues with custom Livewire endpoints.
- Multisite path handling β correctly resolves the current page path from the Referer header during Livewire requests.
View Template Changes
Only relevant if you've published views with php artisan vendor:publish
There are two changes in lf-checkbox-advanced.blade.php & lf-select-advanced.blade.php :
The Alpine counts property is now initialized with PHP rendered data (keys with null values) instead of an empty object, so Alpine knows which filter options exist from the start:
Change: counts: {},
To: counts: @js($this->counts),
The visibility check has been simplified since the keys are now always present:
You can change: x-show="counts && counts[value] !== undefined"
To: x-show="counts[value] != null"
v4.1.1 (Mar 9th, 2026) β
- Fix: Using sort on a taxonomy filter in a multisite setup displayed terms in mixed/incorrect languages instead of the current site's locale.
v4.1.0 (Feb 21st, 2026) β
- Added Laravel Boost guidelines
v4.0.0 (Dec 15th, 2025) β
- Statamic 6 support
- Livewire 4 support
- Fix pagination ?page query string when using custom query sting.
v3.1.4 (Dec 15th, 2025) β
- Fixed: Correctly decode URL encoded values
v3.1.3 (Dec 1st, 2025) β
- Fixed: Lazyload placeholder view was always the default (the parameter didn't get through).
v3.1.2 (Nov 8th, 2025) β
- Fixed: Pagination was not reset when the user was using the "Clear filter" button or when removing an option using LfTags.
v3.1.1 (Nov 5th, 2025) β
- Significantly improve the performance of filter option counts.
v3.1.0 (Oct 22nd, 2025) β
- Added support for the dictionary field. You can now use the built-in or any custom Dictionaries in any filter.
- Fixed ordering for the entries fieldtype so that you can order the field options by title.
v3.0.1 (Oct 20th, 2025) β
- Fixed: Display the key of a select field when the label is not set.
v3.0.0 (Oct 8th, 2025) β
We're excited to announce a new major release for Livewire Filters! This update is accompanied by a brand new documentation website (you're on it!) and a new live demo page where you can see all the features in action.
β¨ What's New β
Upgraded to Tailwind v4 This makes customizing the themeβespecially for minor color changesβmuch easier. If you're updating from a
v2.xversion, please check the installation guide for the required changes.New Advanced Filters with Alpine.js We've added new "advanced" select and checkbox filters! They are ideal for horizontal layouts, offer consistent styling across different platforms, and can be made searchable. See them in action on the horizontal demo page.
New Toggle Filter The new Toggle Filter allows you to create filters with preset values that your users can simply turn on or off.
π Improvements & Fixes β
- Added a
placeholderproperty to all applicable filters. - Upgraded the core dependency to
marcorieser/statamic-livewirev5.0.0. - Made several accessibility improvements.
- Fixed various minor bugs.
v2.7.0 (Mar 29th, 2025) β
- Added support for entries field. You can use an entries relationship field as a filter. The published entries from all associated collections will appear as options.
- When using multi-site and a Statamic entries field to filter your entries, Livewire Filters defaults to using each entry's origin ID. This aligns with Statamic's behavior, where the origin acts as the source of truth unless the field has been localized. This preserves relationships while allowing the associated entry to be translated.
- If you are localizing the entries field itself and want to change this behavior, set the
use_origin_id_for_entries_fieldoption tofalsein the config file. This will make Livewire Filters use the entry ID from the current site for filtering instead.
v2.6.0 (Mar 28th, 2025) β
- Added a
scrollToproperty to LivewireCollection to disable or control the target of the scroll after using the paginator. (#41) - Added a
placeholderproperty to LfTextFilter that allows you to set a placeholder for the input element. (#42) - Fixed an issue where the taxonomy terms would appear in the wrong language when using multi site.
Upgrade Notes:
- The templates for the pagination (
ui/pagination.blade.php) and the LfTextFilter (filters/lf-text-filter.blade.php) need to be upgraded to support the above features. If you have published them, check the original files to copy over the changes.
v2.5.0 (Feb 26, 2024) β
- Laravel 12 support
v2.4.0 (Feb 10, 2024) β
New features
- Lazy Loading: The LivewireCollection component now supports lazy loading.
- LfCount component and
countandactivevariables in theentries-updatesevent. - Added a method to allow clearing all filters at once and added a "Clear all" button in LfTags.
Fixes
- Fixed multi-site queries by using the RestoreCurrentSite trait from the statamic-livewire package.
- Fixed an issue with LfTags when multiple query scopes were used.
- Fixed an error that caused LivewireCollection to render twice when values were preset.
- Added a command to publish the language file.
Other
- New Tips and Performance page in the docs that will contain some tips and best practices.
- Changed the statamic-livewire package installed to marcorieser/statamic-livewire as @marcorieser is the new maintainer.
v2.3.2 (Nov 10, 2024) β
- Fixed a few issues regarding query scopes:
- You can now apply more than one query scope at a time (before the key would have been overridden).
- You can preset a query scope in the LivewireCollection tag and another one in the URL and they will both be correctly preset.
- The Multiselect can now apply for more than one field (previously it only applied randomly for the first).
- The Resrv query scope is now recognized so that it doesn't try to implode the search array.
- If you are not using query scopes or Resrv you can safely skip this release.
v2.3.1 (Nov 7, 2024) β
- Fixed an issue that was caused by the LivewireCollection component responding too slowly when adding filter params.
- Removed the command property from the filters-updated event and cleaned up the code.
- Fixed removing a filter from the LfTags component when the selected value was an array.
v2.3.0 (Nov 6, 2024) β
- New filter: Dual Range Filter. A brand new custom build Livewire component that uses a slider to let the user filter entries that fall into the specified values range.
- More information and documentation: https://livewirefilters.com/usage/dual-range-filter
- Fix: The LfRangeFilter was causing double rendering of the LivewireCollection component (#20). This is now fixed and the default property is deprecated. (you can set a default value in the LivewireCollection component itself)
v2.2.0 (Nov 2, 2024) β
- New feature: Custom URL Query String. Statamic Livewire Filters can now generate easy to read, SEO-friendly URLs when the user is using the filtering system.
- Read the docs: https://livewirefilters.com/advanced/url-query-string#using-the-custom-url-query-string
- Live demo: https://demo.livewirefilters.com/advanced/search/brand/citroen,toyota,vw/categories/crossover-suv/transmission/automaticTransmission
v2.1.0 (Oct 28, 2024) β
- New Feature: Filter options are now sortable. For more information, see the documentation on sorting filter values.
- Documentation: Added a "Common Issues" page to the docs cover common misconfigurations and other issues.
v2.0.1 (Oct 17, 2024) β
- Fixed getting the correct options for array based fields since Statamic changed the way they are saved in statamic/cms#10467
v2.0.0 β
- Statamic v5 and Laravel v11 support.