What’s new in FacetWP 4.5
FacetWP 4.5 was released on March 23, 2026. This update contains the following improvements, new features and bug fixes:
Improvements in creating, saving, and deleting facets and listings
- When creating new facets, listings or Sort facet sort options, the name field is now dynamically checked for duplicate names, and appends a numbered suffix when detected (e.g.
new_facet_1andnew_template_1. This prevents saving facets, listings or sort options with duplicate names and related issues like disappearing facets, listings or sort options in the admin area or front-end. - When deleting a facet or listing from the overview page, it was unclear that you needed to click “Save changes” for the deletion to actually happen. Also, the deletion from the list was instant, with no warning or feedback, sometimes leading to unintended deletions when misclicking in the gear icon dropdown. To fix these issues, we added a warning pop-up on clicking “Delete” and an automatic save when confirming the pop-up.
- We added a ‘Press “Save changes” to apply’ prompt when a change is made in a facet or listing.
Prevention of facet loss when deactivating facet add-ons
With add-on facets in use, if you temporarily deactivated the add-on (e.g. for testing), the add-on facets and their settings were lost when you saved the admin overview page once while the add-on was not active.
This version fixes the issue. If you now deactivate an add-on, its facets are moved to the bottom of the list in the admin overview screen and will show a “disabled” icon to signify they cannot be used or edited:

When hovering over a disabled add-on facet, a tooltip explains that the required add-on is missing. Disabled facets can still be deleted with the cog icon on the right.
Disabled facets can also still be exported and imported. They will have a _missing parameter in their JSON settings.
“Strict query detection” renamed to “Advanced query detection”

The “Strict query detection” setting was renamed to “Advanced query detection”, because too many users in our support were disabling this setting in an attempt to fix their issues, presumably interpreting the “strict” part as a possibly negative thing.
If enabled, the “Advanced query detection” prevents FacetWP from auto-detecting the wrong archive query. In 99% of cases, this setting needs to be enabled, and disabling it will cause FacetWP’s automatic query detection to fail. Only disable it if you have a specific reason, or if you are instructed to do so in support. The setting is enabled by default in FacetWP versions newer than v4.2.3.
The setting now also has a new tooltip explaining the importance of keeping it enabled if in doubt.
Pre-filter Listing Builder listings on author archives
The facetwp_template_use_archive hook could already be used to let FacetWP pre-filter results based on the current category / tag / taxonomy term, or search term(s) on archive pages, by injecting the current term(s) into the Listing Builder listing’s query arguments when filtering. This hook can now also be used for listings on author archive pages, to pre-filter on the current author.
Use FacetWP with a strict Content Security Policy (CSP)
FacetWP’s inline scripts are now added with WP’s wp_print_inline_script_tag() function. This makes it possible to use FacetWP on sites that use a “nonce-based” Strict Content Security Policy (CSP) to mitigate cross-site scripting (XSS).
Using the wp_print_inline_script_tag() function makes it possible to add a nonce attribute to the inline <script> tag that it prints to the page, which is needed to make nonce-based Strict CSP work. The function provides two filter hooks that can be used for this: wp_script_attributes and wp_inline_script_attributes.
The easiest way to implement a nonce-based Strict Content Security Policy (CSP) on the frontend and login screen of your site is to use a plugin like Strict CSP, or this mu-plugin. For more info on how this works, see our tutorial.
Indexing and fixes and improvements
We fixed a range of indexing issues that could happen in specific scenarios:
- We added a check to prevent a re-index with WP-CLI from starting while another indexing process (started with the Re-index button) is already running. When this happens, an error is shown in WP-CLI: “Error: Indexing already in progress”. This prevents multiple indexing processes from running at the same time, which would cause a range of indexing issues.
- Cancelling a running indexing process (by clicking “Stop indexer”), then starting a new indexing process with a method other than the Re-index button (e.g. using the Schedule Indexer add-on, WP-CLI, or custom code using FWP()->indexer->index()) previously did not work, because the
facetwp_indexing_cancelleddatabase option was not properly cleaned up. In this new version, when cancelling indexing, all index tracking options in thewp_optionstable are immediately cleaned up, and thefacetwp_temp_tableis immediately deleted, preventing several issues with restarting a new indexing process. - The internal recurring
facetwp_indexer_croncron event (scheduled with wp_schedule_single_event()) that is used for tracking indexing progress (and automatically resuming the process when it stalls), is now only created during indexing itself, when it is needed. If there is no full re-indexing process running, there will be no cron schedule at all. Previously, it was created on page load and then was firing and re-created every five minutes. This fix prevents the cron schedule from running unnecessarily, and prevents the pile-up of log entries in certain cron plugins (like Calvalcade). - The “Enable automatic indexing” setting now displays a warning message when the facetwp_indexer_is_enabled hook is used to disable automatic indexing (instead of the setting), because in this scenario, the setting is overridden by the hook:

The ‘Enable automatic indexing’ warning when the facetwp_indexer_is_enabledhook is in use.
No more “The index table is empty”
We fixed a timing issue that often caused a puzzling “The index table is empty” message after finishing a successful re-index with the Re-index button. This was happening most often in sites with a lot of rows in the indexing table.
Compatibility with WordPress 6.9
We fixed an issue that some users were experiencing after updating to WP v6.9.
In these situations, WP’s new template enhancement output buffer conflicted with FacetWP’s output buffering, causing JSON errors and malfunctioning facets on refresh.
New User Selections hooks
We added two new hooks to make it easier to customize which facet types and individual facets are displayed in the User Selections facet.
We also added four new hooks that can be used to customize every aspect of the User Selections’ HTML output. These hooks also make it possible to style individual facet selections as single, wrapping list items, making the User Selections behave better on smaller widths if a facet has a lot of selections.
Other fixes and improvements
Front-facing changes
- We fixed a bug in the Open Marker Spiderfier integration of the Map facet that was causing JavaScript errors when (un)spiderfying and hovering markers.
- We fixed a fatal error that happened when using a facet name as an array in the URL (e.g.
/?_myfacetname[]=value), which could happen when doing a vulnerability scan of a site using FacetWP. - We fixed an issue with the “Strict query detection” setting (now called “Advanced query detection”) not showing up in Debug Mode for older installations that never saved the setting.
- We added a
z-index: 999;rule to the CSS of the Proximity facet’s.location-resultsdropdown. Because this dropdown is absolutely positioned but had no explicitz-index, in some sites it was disappearing behind other absolutely or relatively positioned elements. - We fixed a bug in the Hierarchy facet that caused the facet value output in the facet to not run through our sanitizing function.
- We added an
!importantdeclaration to the CSS of the Load More Pager facet button when it is hidden:How to use custom CSS?
CSS code can be placed in your (child) theme's style.css file. Alternatively, you can add it manually between
<style>tags in the<head>section, in your (child) theme's header.php file. You can also load it with a hook in your (child) theme's functions.php file, or in the Custom Hooks add-on. To load the code only on pages with facets, use thefacetwp_scriptshook. To load it on all pages, usewp_headorwp_footer. Or you can use a code snippets plugin. More info.facetwp-load-more.facetwp-hidden { display: none !important; }This change fixes an issue with the button not being hidden when there are no further results to load. This happened quite often in sites with themes that use
display: block;ordisplay: inline-block;on buttons, and in doing so, depending on the selector used, then overwrite thedisplay: none;for the.facetwp-hiddenclass of the button. - We fixed a reset bug in the fSelect facet: if you typed in a search keyword in the facet’s search box, then clicked out of the facet without clearing the keyword, then removing the keyword again in one go (using backspace), the results in the dropdown did not reset.
- We fixed a bug in the Reset facet that caused the button/link to not show if its “Auto-hide” setting was enabled, and there was a pre-selection in one or more other facets, created with the facetwp_preload_url_vars hook. The issue was also fixed in the Mobile Flyout add-on.
- We fixed a bug in the Dropdown facet and Sort facet that caused these facet types to not update their
selectedattributes correctly when used. - We fixed a wrong
z-indexthat caused WP sidebar submenus to be displayed below FacetWP’s semi-transparent overlay on settings screens of programmatically added facets and listings. - We added an
is_archiveoption to Debug Mode that shows whether or not the page is an archive template. This saves having to ask this in support, when the theme does not output archive body classes. - We fixed a bug in the Reset facet that caused a “Per page” Pager facet type to not reset. Note that if you don’t want the “Per page” facet to be reset, you can still add it to the Reset facet’s excluded facets.
- We fixed a bug in the User Selections facet that happened when there were commas used in the keywords for a Search facet or Autocomplete facet. When a URL was loaded with facet values containing commas, the User Selections displayed only the first item. Values with commas are now properly handled in the User Selections.
- We fixed another bug in the User Selections facet that happened when using a Search facet. Search facets can have quoted search. E.g.
"colorful shirt"(with the double quotes) searches for this exact phrase. When loading a URL with a quoted search term value for the Search facet, the value showed up with encoded quotes ("colorful shirt") in the User Selections facet. The quotes now show up correctly. - We fixed another bug in the User Selections facet that caused Dropdown facet selections to not update their
data-valueattribute correctly. - We fixed a bug in the Sort facet that happened when a listing template query had a
meta_query with multiple conditions and anORrelation set. When using a Sort facet and sorting by a custom field, the listing’smeta_queryconditions were ignored because the Sort facet’smeta_querywas merged into it, also usingORmode. This is now fixed: if the listing’smeta_queryhas anORrelation set, the Sort facet’smeta_querywill now be appended to it instead of merged into it, and will automatically use (the default)ANDmode.
Under the hood
- FacetWP uses a blacklist of post types that should be ignored in its automatic query detection. We refactored this blacklist into a helper function so that it can be reused in other places, like our add-ons. The blacklist is now customizable with a new
facetwp_post_types_blacklistfilter hook. A few new ACF post types were added to the list. - FacetWP gets all postmeta fields that can be used as data source in the admin area. With an existing
facetwp_excluded_custom_fieldsfilter it was already possible to exclude specific custom fields. This version adds a newfacetwp_excluded_custom_fields_likefilter, which makes it possible to exclude fields based on a partial match within theNOT LIKESQL clause. It can be used like this:How to use custom PHP code?
PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info
add_filter( 'facetwp_excluded_custom_fields_like', function( $not_like ) { $not_like[] = '_crp_cache_'; return $not_like; });This specific example fixes an issue that resulted in the admin area returning a
404(or403or500) error, caused by the Contextual Related Posts plugin storing a new postmeta cache row on each visit. - We added a check to prevent script errors when users try to enable accessibility support the wrong way, by loading accessibility.js with the
facetwp_assetshook. - We added several checks and fail-safes in FacetWP’s updater code to prevent PHP warnings and wrong data when
api.facetwp.comis unreachable during an update check, which recently happened in a Cloudflare outage. This also fixes a bug that was causing thefacetwp_activationoption in the database to not be updated if the update request returns an error.