This add-on lets you display facets alongside supported WordPress blocks, in classic and block themes.

Supported blocks

The following blocks are supported and can be used to create FacetWP compatible listings. Note that all blocks need to be enabled for FacetWP to be filterable by facets.

Source/Plugin Block name Block type
WordPress WordPress Query Loop blockQuery Loop
WordPress Posts  List blockPosts List
WordPress Latest Posts blockLatest Posts
WP Query Loop
WP Query Loop
posts loop
WooCommerce WooCommerce Products (Beta) blockProducts (Beta)
* Deprecated. See warning banner below
WooCommerce Product Collection blockProduct Collection

Notes:

  • The Product Collection block comes with its own set of product filtering, sorting, and pagination blocks, which all are incompatible with FacetWP. Remove these blocks and use facets instead.
WP Query Loop
 
WP Query Loop
GenerateBlocks GenerateBlocks Query Loop blockQuery Loop (v1)
GenerateBlocks Query blockQuery (v2)

Notes:

  • When using GenerateBlocks Pro, the Query (v2) block has a “Query Type” setting, for which only the “Post Query” option is supported. FacetWP cannot filter post meta or options.
  • See this page for how to switch between v1 and v2 blocks.
GB Query Loop
GB Query Loop
Kadence Blocks Kadence Posts blockPosts posts loop
Stackable Stackable Posts blockPosts posts loop
Spectra Spectra Post Grid blockPost Grid posts loop
Spectra Pro (v1.2.0+) Spectra (Advanced) Loop Builder block(Advanced) Loop Builder

Notes:

  • The Spectra Pro Loop Builder block comes with its own set of filtering, sorting, searching, and pagination blocks, which all are incompatible with FacetWP. Remove these blocks and use facets instead.
Spectra Query Loop
Otter Blocks Otter Blocks Posts blockPosts posts loop

The FacetWP Blocks add-on (v0.3+) adds the following FacetWP blocks:

Plugin Block name
FacetWP FacetWP blockFacet
FacetWP blockListing

Supported WordPress context

This add-on was tested with WordPress v6.2.3 and newer versions. It may or may not work with older versions. Due to the highly evolving nature of the WordPress Block- and Site Editor, future WordPress updates may unexpectedly break functionality. Let us know if you experience any issues.

This add-on expects the Block Editor to be functional. So don’t use any code or plugins to “disable Gutenberg” or reinstate the Classic Editor.

Don’t use the Gutenberg plugin

You don’t need the Gutenberg plugin to use the WordPress Block Editor.

Gutenberg is now a “beta plugin”, giving access to bleeding-edge and experimental Gutenberg features. It is meant to be used by developers who need to test features of the Block- and Site Editor before they are officially released. As such, this plugin may contain non-final code that is possibly incompatible with FacetWP’s Blocks add-on or other block plugins.

To prevent issues, don’t install the Gutenberg plugin, or deactivate it, unless you really need it.

Usage

Follow these steps to set up FacetWP with one of the supported blocks:

  1. Download the Blocks add-on from your account page, then install and activate it.
  2. Open a new or existing page in the Block Editor, or a template page in the Site Editor (if you are using a block theme), and add one of the supported blocks to the page.
  3. Enable FacetWP for a supported block.
    Enable FacetWP for a supported block.

    When this add-on is active, supported blocks will display an extra “Enable FacetWP” setting in the block settings in the right sidebar. Enable this setting to let FacetWP dynamically filter this block listing with facets. Note that the FacetWP Listing block does not have this setting, it will just work by itself.

  4. Add a FacetWP shortcode to a Shortcode block.
    Add a FacetWP shortcode to a Shortcode block.

    Next, add one or more facets to the page. The easiest is to use FacetWP’s own built-in Facet block (available in v0.3+ of the Blocks add-on). Alternatively, you can paste each facet shortcode into a separate Shortcode block.

  5. If needed, add pagination with a Pager facet, and/or sorting with a Sort facet, both of which can be added with a Facet block. Note that Pagination blocks are not supported. Some supported blocks automatically add a Pagination block, which needs to be deleted.
  6. If your block is a Query Loop type block, it is possible to add a custom-built No Results block to replace the default “Nothing found” message. Some blocks, like a custom-defined Product Collection block, and the GenerateBlocks Query (v2) block, add a No Results block automatically.
  7. If needed, customize/translate the “Nothing found” message or the No Results block content.

FacetWP blocks

Insert built-in FacetWP blocks.
Insert built-in FacetWP blocks.

Since v0.3, the FacetWP Blocks add-on comes with two built-in FacetWP blocks:

  1. Facet – adds a facet.
  2. Listing – adds a Listing Builder listing.

The FacetWP Facet block

The FacetWP Facet block settings.
The FacetWP Facet block settings.

With a Facet block you can add an existing facet to your page. The block is a convenient alternative to adding facet shortcodes in a Shortcode block.

After adding the block to your page, use the “Select a facet” dropdown in the placeholder or the sidebar to select one of your existing facets.

The dropdown will show all previously created facets.

At the bottom of the dropdown, you can select the User Selections facet, which is not a facet you can create (and does not appear in the back-end facet overview in the FacetWP settings).

The “Heading” setting

Optionally, you can add a facet heading/label by toggling the “Heading” setting and entering text in the Heading block that appears above the facet placeholder after selecting a facet. You can determine the HTML tag used in the inline block settings and style it further in the sidebar. Disabling the Heading setting will remove the facet’s Heading block.

The “Hide when empty” setting

If you want to hide “empty” facets, including their heading, enable the “Hide when empty” setting.

Facets can become empty because they have no choices left after filtering. Facets can also be empty before filtering, if they have no choices indexed/available for the posts in the listing. Or if the listing template’s query has 0 results. The setting also hides facets if the listing template’s query has 0 results, before or after filtering.

To be able to hide empty facets, the 'Show ghosts' setting must be disabled.
To be able to hide empty facets, the “Show ghosts” setting must be disabled.

Make sure the facets that have their “Hide when empty” setting enabled, do not have the “Show ghosts” setting enabled (if they have this setting). Because facets with ghosts will never become empty.

Note that the “Hide when empty” setting is only available for facet types that store their number of choices left. This means that the setting will not display for the following facet types:

To hide these facet types (or any other facet, or their container/wrapper element) when there are no results, you can use the Conditional Logic add-on. Create a rule with the Condition set to a “Result count” of 0. Add one or more Actions to hide the desired facet(s), or their container/wrapper element (if needed with a custom selector).

Facet placeholders in the block editor

Facets will not display in the block editor. A placeholder is shown instead:

An example placeholder for a Radio facet, with a heading block.
An example placeholder for a Radio facet, with a heading block.

Check your front-end page to see if your facets are functioning correctly. If they are not appearing, make sure you also have added a listing to the page. This can be a supported block, a Listing Builder listing (added with a Listing block or Shortcode block), or any other supported listing template type. Make sure there is only one FacetWP-enabled listing on a page.

The FacetWP Listing block

The FacetWP Listing block settings.
The FacetWP Listing block settings.

With a Listing block you can add an existing Listing Builder listing template to your page. It is a convenient alternative to adding listing shortcodes in a Shortcode block.

After adding the Listing block to your page, use the “Select a listing” dropdown in the placeholder or the sidebar to select one of your previously created Listing Builder listings.

Unlike the Facet block, the Listing block will show your listing, including its full layout, in the editor.

Note that if you want to use a Listing block on an archive template (instead of on a normal page), see this section on how to let FacetWP use (or ignore) the archive query.

Add a static listing

How to add a static listing.
How to add a static listing.

By enabling the Listing block’s “Static” setting, you can add a static Listing Builder listing to the page. A “static” listing is a listing that does not react to facets.

You can even add multiple static listings to a page, also to a page that already has a “normal” filterable (non-static) listing. But there should be only one filterable (non-static) listing on a page.

Note that static Listing Builder listings can also be added with a shortcode or PHP. When using a shortcode, you can add them with a Shortcode block.

Using blocks on archive templates

In WP v6.7+, enable Query Type 'Default' for Query Loop type blocks on archive pages.
In WP v6.7+, enable Query Type “Default” for Query Loop type blocks on archive pages.
In WP pre-v6.7, or for the GenerateBlocks Query Loop (v1) block, the GenerateBlocks Query (v2) block, or the WooCommerce Products (Beta) block, enable 'Inherit query from template' on archive pages.
In WP pre-v6.7, or for the GenerateBlocks Query Loop (v1) block, the GenerateBlocks Query (v2) block, or the WooCommerce Products (Beta) block, enable “Inherit query from template” on archive pages.

If you use a supported block on an archive template (in classic as well as block themes), make sure the query is using the native archive query, by enabling Query Type “Default”.

In WP versions older than v6.7, and for the GenerateBlocks Query Loop (v1) block, the GenerateBlocks Query (v2) block, or the WooCommerce Products (Beta) block, enable “Inherit query from template”.

This setting is only visible in archive templates, and in the following Query Loop type blocks:

  • WordPress Query Loop block
  • WordPress Posts List block
  • WooCommerce Products (Beta) block
  • WooCommerce Product Collection
  • GenerateBlocks Query Loop (v1) block
  • GenerateBlocks Query (v2) block

Note that to customize the query for these block types, when used on archive templates with the mentioned setting enabled, you need to use the pre_get_posts hook, as described below.

The Spectra Pro (Advanced) Loop Builder block for some reason does not have an “Inherit query from template” setting. This means that when you use this block on an archive template, this block will create a new custom WP_Query. In this situation, you need to tell FacetWP to ignore the archive query, because FacetWP prioritizes the archive query.

If you want to use a FacetWP Listing block on an archive template, see this section on how to let FacetWP use (or ignore) the archive query.

Let FacetWP ignore archive queries for blocks

If you have a reason to use a block on an archive template without enabling the “Default” Query Type or “Inherit query from template” setting, you need to tell FacetWP to ignore the archive query and use the block’s custom query instead. The reason is that otherwise, FacetWP will automatically detect and prioritize the archive query.

This can be done with the facetwp_is_main_query hook. Add the following code to your (child) theme’s functions.php:

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_is_main_query', function( $is_main_query, $query ) { if ( $query->is_archive() && $query->is_main_query() ) { $is_main_query = false; } return $is_main_query; }, 10, 2 );

Add pagination and sorting

This add-on supports using Sort facets and Pager facets, including the Load More type Pager facet. You can add these facets with a Facet block, or by pasting their shortcode in a Shortcode block.

It does not support Pagination blocks, or pagination that is added by settings in any of the supported blocks themselves (with one exception: the Spectra Post Grid block’s pagination).

The add-on also does not support any sorting, filtering or search blocks, like the WooCommerce Catalog Sorting block and other product filtering blocks, and the Spectra Pro (Advanced) Loop Builder block’s filtering, sorting, reset and searching blocks. Remove these blocks if added automatically, and use facets instead.

Remove / don’t add Pagination blocks

The add-on does not work with a separate Pagination block (which can be added when the child “Post Template” block in a Query Loop type block is selected.

Delete the automatically added Pagination block. Use a Pager facet instead, which you can add with a Facet block.
Delete the automatically added Pagination block. Use a Pager facet instead, which you can add with a Facet block.

Note that the WooCommerce Product Collection and Products (Beta) blocks, some Query Loop / Posts List block layout patterns, the GenerateBlocks Query (v2) block, and the Spectra Pro (Advanced) Loop builder block automatically add one or more Pagination blocks on insertion. These Pagination blocks need to be removed manually, as they will not work. Use a Pager facet instead, which you can add with a Facet block, or by pasting its shortcode in a Shortcode block.

GenerateBlocks Query Loop (v1) block pagination

The GenerateBlocks Query Loop (v1) block has a button in the top/floating block toolbar to add pagination. This type of pagination should not be used as it is incompatible with FacetWP. Use a Pager facet instead, which you can add with a Facet block, or by pasting its shortcode in a Shortcode block.

GenerateBlocks Query (v2) block pagination

Delete the GenerateBlocks Query (v2) pagination blocks. Use a Pager facet instead, which you can add with a Facet block.
Delete the GenerateBlocks Query (v2) pagination blocks. Use a Pager facet instead, which you can add with a Facet block.

The GenerateBlocks Query (v2) block adds a Container block with three pagination blocks. This type of pagination is incompatible with FacetWP. Remove the Container block with its three child pagination blocks. Use a Pager facet instead, which you can add with a Facet block, or by pasting its shortcode in a Shortcode block.

Stackable Posts block pagination

If you have Stackable Premium installed, the Stackable Posts block can have a Pagination block or a Load More Button block added (with the + icon at the bottom of the Posts block). Both of these blocks are incompatible with FacetWP. Use a Pager facet instead, which also has a Load More Pager type if needed. You can add it a Facet block, or by pasting its shortcode in a Shortcode block.

Spectra Post Grid block pagination

The Spectra Post Grid block's Pagination settings.
The Spectra Post Grid block’s Pagination settings.

The Spectra Post Grid block has a “Post Pagination” setting. This pagination can be used with FacetWP. If enabled, the “Pagination Type” can be set to “Ajax” or “Normal”. It will work no matter which type you choose, as the add-on will intercept the pagination clicks.

Alternatively, you can use a Pager facet, which you can add with a Facet block, or by pasting its shortcode in a Shortcode block.

The Spectra Post Grid block's Page Limit setting.
The Spectra Post Grid block’s Page Limit setting.

Note that this block also has a “Page Limit” setting which limits the number of pages in the pagination. Be aware that in Pager facets (of all Pager types, also Result Counts) this setting is ignored. It does work with the block’s own pagination, so if you don’t see all results, make sure the Page Limit is set high enough to show all posts in the listing query.

One other caveat is that this block’s own pagination is repeated when using a “Load more” type Pager facet. So don’t combine the block’s own pagination with a “Load more” facet.

Query Loop block structure and block nesting

A Query Loop block with an added No Results block.
A Query Loop block with an added No Results block.

The supported blocks that are marked as “Query Loop type” blocks in the above table are all based on WP’s core Query Loop block structure.

These blocks are a set of nested blocks: they consist of at least a main parent container block and a child Post Template block. This Post Template block determines the contents of each individual post in the loop. It consists of one or more nested child blocks, depending on the initially chosen “layout pattern” and additional blocks you may add. Within the Post Template block, you can build the individual posts however you like.

The main parent block can also contain other direct child blocks, such as a No Results block, as shown in the image above.

The default nesting structure of a GenerateBlocks Query Loop (v1) block.
The default nesting structure of a GenerateBlocks Query Loop (v1) block.

This add-on also supports (deeper) block nesting. All supported blocks can be nested in other container blocks (like Group, Container, Column, or Section blocks).

When using a Query Loop type block, its child Post Template block can also be nested in other container blocks if needed, like for example in the GenerateBlocks Query Loop (v1) block, where the Post Template block is nested within a Grid block, as shown in the image on the right.

The default nesting structure of a GenerateBlocks Query (v2) block.
The default nesting structure of a GenerateBlocks Query (v2) block.

The GenerateBlocks Query (v2) block has an even more elaborate structure with a Looper and Loop Item block, as shown in the image on the right.

This block also adds a Container block with three pagination blocks. These pagination blocks need to be removed, because they don’t work with FacetWP. Use a Facet block with a Pager facet instead.

The block’s own No Results block, with its child block(s), can be used with FacetWP. If needed, its output can be overridden.

Add a custom No Results block

Every supported block has a default “Nothing found” message that displays when there are no results (for example when using a Search facet). This message can easily be customized, translated or overridden.

In Query Loop type blocks (except in the GenerateBlocks Query Loop (v1) block and the Spectra Pro (Advanced) Query Loop block, which has a “If Posts Not Found” setting), it is also possible to replace the default message with a No Results block containing custom-built content (consisting of other blocks).

Some blocks, like a custom-defined Product Collection block, and the GenerateBlocks Query (v2) block, add a No Results block automatically.

To add a No Results block manually, first select a direct child block of the main parent block. The No Results block will then be available to choose from the Block Inserter.

Add a No Results block directly before or after the Post Template block.
Add a No Results block directly before or after the Post Template block.

In a WP Query Loop block, if you add the No Results block as a direct child block of the main Query Loop block, it can be placed before or after the Post Template block. However, if you nest it in another block for some reason, it has to be placed before the Post Template block.

By default, the No Results block only contains a Paragraph child block, which you can use to add your custom message. You can change this block to something else, or add other child blocks to build whatever layout you want to display when the main parent block’s query returns no results.

If you need more flexibility, the contents of a No Results block can also be customized or completely overridden with a hook.

Nesting No Results blocks

A nested No Results block needs to be placed above the Post Template block, not below it.
A nested No Results block needs to be placed above the Post Template block, not below it.

In a WP Query Loop type block, if the No Results block is nested in another block for some reason, its container needs to be placed before the Post Template block (or its container block if it is nested) in the block tree.

If this is not the case, the No Results block will not work and the Query Loop block will show the default no results message. Stand-alone (non-nested) No Results blocks can be placed before or after the Post Template block.

Customize, translate, or override the “Nothing found” message or No Results block content

Both the default “Nothing found” message and the contents of a custom No Results block can be changed or translated in various ways.

The default “Nothing found” message is a translatable string that can be translated with the internationalization function __() (e.g. with a translation plugin), or with the WordPress gettext filter:

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( 'gettext', function( $translated_text, $text, $domain ) { if ( 'fwp-front' == $domain ) { if ( 'Nothing found.' == $translated_text ) { $translated_text = 'Niets gevonden.'; } } return $translated_text; }, 10, 3 );

In a multi-lingual site, you can also translate the “Nothing found” message with the facetwp_i18n hook:

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_i18n', function( $string ) { if ( isset( FWP()->facet->http_params['lang'] ) ) { $lang = FWP()->facet->http_params['lang']; $translations = []; $translations['nl']['Nothing found.'] = 'Niets gevonden.'; $translations['de']['Nothing found.'] = 'Nichts gefunden.'; if ( isset( $translations[ $lang ][ $string ] ) ) { return $translations[ $lang ][ $string ]; } } return $string; });

Override the “Nothing found” message or No Results block content with a hook

The default “Nothing found” message and the contents of a No Results block can both also be customized or completely overridden with a hook. This makes it possible to output any custom HTML when there are no results.

The hook to use depends on the block type. The following snippets need to be added to your (child) theme’s functions.php:

WP Query Loop block / WP Posts List block / WooCommerce Product Collection block / WooCommerce Products (Beta) block
For the WordPress Query Loop block, WordPress Posts List block, WooCommerce Product Collection block, and the WooCommerce Products (Beta) block, use:

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_blocks_query_loop_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
WP Latest Posts block
For the WordPress Latest Posts block, use:

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_blocks_latest_posts_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
GenerateBlocks Query Loop (v1) block
For the GenerateBlocks Query Loop (v1) block, use:

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_blocks_gb_query_loop_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
GenerateBlocks Query (v2) block
For the GenerateBlocks Query (v2) block, use:

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_blocks_gb_query_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
Kadence Blocks Posts block
For the Kadence Blocks Posts block, use:

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( 'kadence_blocks_posts_empty_query', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
Stackable Posts block
For the Stackable Posts block, use:

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_blocks_stk_posts_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
Spectra Post Grid block
For the Spectra Post Grid block, use:

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_blocks_uagb_postgrid_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
Add a custom 'Nothing Found' message in the Spectra Post Grid block.
Add a custom “Nothing Found” message in the Spectra Post Grid block.

Note that the above hook also overrides the Spectra Post Grid block’s own “If Posts Not Found” setting, with which you can set a custom “Display Message”. This setting accepts text and HTML.

If you leave this setting empty, the default message is “Nothing found.”.

Spectra Pro (Advanced) Loop Builder block
For the Spectra Pro (Advanced) Loop Builder block, use:

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_blocks_uagb_loop_builder_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );
Add a custom 'Nothing Found' message in the Spectra Pro (Advanced) Loop Builder block.
Add a custom “Nothing Found” message in the Spectra Pro (Advanced) Loop Builder block.

Note that the above hook also overrides the Spectra Pro (Advanced) Loop Builder block’s own “If Posts Not Found” setting, with which you can set a custom “Display Message”. This setting accepts text and HTML.

If you leave this setting empty, the default message is “Nothing found.”.

Otter Blocks Posts block
For the Otter Blocks Posts block, use:

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_blocks_themeisle_blocks_posts_no_results', function( $no_results_html ) { // customize $no_results_html, or completely override it: $no_results_html = '<p>' . facetwp_i18n( __( 'Niets gevonden.', 'fwp-front' ) ) . '</p>'; return $no_results_html; }, 10 );

Customize block queries

To customize a block’s query arguments, you can use a hook. The specific hook to use depends on the block type and its template context. The following snippets need to be added to your (child) theme’s functions.php:

Customize WP Query Loop type block queries

To customize the query arguments on normal (non-archive) pages, for the WordPress Query Loop and Posts List blocks, and the WooCommerce Product Collection and Products (Beta) blocks, use the query_loop_block_query_vars hook. On archive templates, use the pre_get_posts hook instead, as explained below.

In this example, we restrict the hook to blocks that are enabled for FacetWP. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'query_loop_block_query_vars', function( $query, $block, $page ) { if ( is_page(123) && ( strpos( ( $classname = $block->parsed_block['attrs']['className'] ?? '' ), 'facetwp-template') !== false ) ) { // Adapt the is_page() conditional as needed $query['posts_per_page'] = 9; } return $query; }, 11, 3 ); // Important: use with priority 11 or later.

Customize Query Loop type block queries on archive templates

In WP v6.7+, enable Query Type 'Default' for Query Loop type blocks on archive pages.
In WP v6.7+, enable Query Type “Default” for Query Loop type blocks on archive pages.
In WP pre-v6.7, or for the GenerateBlocks Query Loop (v1) block, the GenerateBlocks Query (v2) block, or the WooCommerce Products (Beta) block, enable 'Inherit query from template' on archive pages.
In WP pre-v6.7, or for the GenerateBlocks Query Loop (v1) block, the GenerateBlocks Query (v2) block, or the WooCommerce Products (Beta) block, enable “Inherit query from template” on archive pages.

If you use a Query Loop type block on an archive template (in classic as well as block themes), and you have enabled the “Default” Query type (or “Inherit query from template”) setting (so it uses the native archive query), the above-mentioned query_loop_block_query_vars hook will not work or will lead to pagination issues. The same applies to both below-mentioned GenerateBlocks v1 and v2 query hooks.

On archive templates, you need to always use the pre_get_posts hook.

The following example only runs on the products post-type archive. Adapt the condition as needed: for example, for all archives, use is_archive(), and for the blog page is_home().

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_action( 'pre_get_posts', function( $query ) { if ( is_post_type_archive('product') ) { $query->set( 'posts_per_page', 9); } }, 10);

Customize Latest Posts block queries

For the WordPress Latest Posts block, you can use the pre_get_posts hook, but its priority needs to be set to 11. In this situation, you can check for the facetwp query variable as conditional, so it will only run on Latest Posts blocks that are enabled for FacetWP. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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_action( 'pre_get_posts', function( $query ) { if ( is_page(123) && $query->get('facetwp') == true ) { // Adapt is_page() conditional as needed $query->set( 'posts_per_page', 9); } }, 11);

Customize GenerateBlocks Query Loop (v1) block queries

For the GenerateBlocks Query Loop (v1) block, use GenerateBlocks’ generateblocks_query_loop_args hook. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'generateblocks_query_loop_args', function( $query_args, $attributes, $block ) { if ( is_page(123) && ( ! empty( $attributes['className'] ) && strpos( $attributes['className'], 'facetwp-template' ) !== false ) ) { // Adapt is_page() conditional as needed $query_args['posts_per_page'] = 9; } return $query_args; }, 10, 3 );

On archive templates, when using “Inherit query from template”, use the pre_get_posts hook instead.

Customize GenerateBlocks Query (v2) block queries

For the GenerateBlocks Query (v2) block, use GenerateBlocks’ generateblocks_query_wp_query_args hook. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'generateblocks_query_wp_query_args', function( $args, $attributes, $block) { if ( is_page(123) && ( $attributes['enableFacetWP'] ?? null ) === true ) { // Adapt is_page() conditional as needed $args['posts_per_page'] = 3; } return $args; }, 10, 3 );

On archive templates, when using “Inherit query from template”, use the pre_get_posts hook instead.

Customize Kadence Blocks Posts block queries

For the Kadence Blocks Posts block, use Kadence Blocks’ kadence_blocks_posts_query_args hook. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'kadence_blocks_posts_query_args', function( $query_args ) { if ( is_page(123) ) { // Adapt is_page() conditional as needed $query_args['posts_per_page'] = 9; } return $query_args; }, 10 );

Customize Stackable Posts block queries

For the Stackable Posts block, use Stackable’s stackable/posts/post_query hook. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'stackable/posts/post_query', function( $query_args ) { if ( is_page(123) ) { // Adapt is_page() conditional as needed $query_args['posts_per_page'] = 9; } return $query_args; }, 10 );

Customize Spectra Post Grid block queries

For the Spectra Post Grid block, use Spectra’s uagb_post_query_args_grid hook. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'uagb_post_query_args_grid', function( $query_args ) { if ( is_page(123) ) { // Adapt is_page() conditional as needed $query_args['posts_per_page'] = 9; } return $query_args; }, 10 );

Customize Spectra Pro (Advanced) Loop Builder block queries

For the Spectra Pro v1.2.0+ (Advanced) Loop Builder block, use the spectra_loop_builder_main_query_args hook. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'spectra_loop_builder_main_query_args', function( $query ) { if ( is_page(123) ) { // Adapt is_page() conditional as needed $query['posts_per_page'] = 9; } return $query; }, 10 );

For this block, you can also use the query_loop_block_query_vars hook on the parent block’s Wrapper child block. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'query_loop_block_query_vars', function( $query, $block, $page ) { if ( is_page(123) && $block->parsed_block['blockName'] === 'uagb/loop-wrapper' ) { // Adapt is_page() conditional as needed $query['posts_per_page'] = 9; } return $query; }, 10, 3 );

Note that the above-mentioned spectra_loop_builder_main_query_args hook runs after the query_loop_block_query_vars hook.

Customize Otter Blocks Posts block queries

For the Otter Blocks Posts block, use Otter Blocks’ themeisle_gutenberg_posts_block_query hook. Add other Conditional Tags to further restrict the hook as needed. This example only runs on a page with ID 123:

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( 'themeisle_gutenberg_posts_block_query', function( $query, $attributes ) { if ( is_page(123) && $attributes['enableFacetWP'] === true ) { // Adapt is_page() conditional as needed $query['posts_per_page'] = 9; } return $query; }, 10, 2 );

Use blocks and FacetWP in WordPress .html templates

With this add-on installed, it is possible to use supported blocks in WordPress .html templates, the type of template used by block themes.

For example, suppose you are using a block theme that has a search.html template for the search results page, and you want it to use a Query Loop block with a few facets above it to let the user filter the search results.

The quickest way to do this is:

  1. Create a new (temporary) page.
  2. Add a Query Loop block to the page with the Block Inserter, enable FacetWP with the “Enable FacetWP” setting. Make sure to enable the Query Type “Default” (or “Inherit query from template”) setting, because the search template is an archive, and we need the Query Loop block to use the native archive query.
  3. Enable Code Editor view in the WordPress block editor.
    Enable Code Editor view in the WordPress block editor.

    Create a few facets. In the example below, we created a Search facet and a Pager facet.

  4. Add a Facet block for each facet. Or you can use a Shortcode block for each facet and copy your facet shortcode(s) into them.
  5. Switch the Block Editor to “Code Editor” view, as shown in the image on the right.
  6. Copy the whole block code from the Code editor.
  7. Open the search.html theme file and replace the part of the block code that is the content with the copied block code from your temporary page. Make sure to leave the header and footer template part intact, as well as any container or group block(s).
  8. You can now remove the temporary page, or keep it as draft for future changes.

Your search.html file will now look something like the following code, and will work with the facets:

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

<!-- wp:template-part {"slug":"header","tagName":"header"} /--> <!-- wp:group {"tagName":"main","style":{"spacing":{"margin":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"layout":{"type":"constrained"}} --> <main class="wp-block-group" style="margin-top:var(--wp--preset--spacing--70);margin-bottom:var(--wp--preset--spacing--70)"> <!-- wp:query-title {"type":"search","align":"wide","style":{"spacing":{"margin":{"bottom":"var:preset|spacing|50"}}}} /--> <!-- Start pasted Shortcode blocks with facets, and Query Loop block --> <!-- wp:shortcode --> [facetwp facet="search"] <!-- /wp:shortcode --> <!-- wp:shortcode --> [facetwp facet="pager_numbers"] <!-- /wp:shortcode --> <!-- wp:query {"queryId":1,"query":{"perPage":5,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true},"enableFacetWP":true} --> <div class="wp-block-query"><!-- wp:post-template --> <!-- wp:post-title /--> <!-- wp:post-excerpt /--> <!-- /wp:post-template --> <!-- wp:query-no-results --> <!-- wp:paragraph {"placeholder":"Add text or blocks that will display when a query returns no results."} --> <p>No results found.</p> <!-- /wp:paragraph --> <!-- /wp:query-no-results --></div> <!-- /wp:query --> <!-- End pasted blocks --> </main><!-- /wp:group --> <!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Notice "enableFacetWP":true in the Query Loop block settings on line 16, which is the result of the “enable FacetWP” setting.

Disable inline block styles

WordPress dynamically adds a range of inline default CSS styles for each block, as well as corresponding classes in the block’s HTML.

It is possible to remove these inline styles. The method depends on your WordPress version and the theme used. Due to the evolving nature of the WP Block- and Site Editor, the way to do this will probably change over time. At the time of writing, adding the following lines to your (child) theme’s functions.php seems to do the trick for most styles.

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

// Opt out of generated layout styles with the 'disable-layout-styles' support flag add_theme_support( 'disable-layout-styles' ); // These two lines will probably not be necessary eventually remove_filter( 'render_block', 'wp_render_layout_support_flag', 10, 2 ); remove_filter( 'render_block', 'gutenberg_render_layout_support_flag', 10, 2 ); // Needed if you have the Gutenberg plugin installed

More info about the various inline styles and ways to remove them can be found in this article.

Known issues, incompatibilities, and unsupported block settings

There are a few things known to not work with this add-on:

Layout patterns with multiple query loops

Don't choose or create layout patterns with multiple Query Loop blocks. FacetWP should only be enabled for one block on a page.
Don’t choose or create layout patterns with multiple Query Loop blocks. FacetWP should only be enabled for one block on a page.

When adding a Query Loop type block, you will be prompted to choose a layout pattern. WordPress currently has at least one layout pattern that adds two separate Query Loop blocks. Enabling FacetWP on multiple Query Loop (or other) blocks is not supported. Choose a layout pattern with only one Query Loop block for FacetWP to interact with.

In general, make sure to have only one block on a page or template that is enabled for FacetWP.

Don’t use the query offset setting

Don’t use a block’s query query “offset” setting (if available). In general, using query offset is incompatible with FacetWP, because it is also applied after using facets. Another issue is that offsets breaks pagination, because it is used by WordPress internally to calculate which posts need to be on which paged page.

See our offset tutorial for an alternative offset solution.

Don’t use any WooCommerce product filtering or sorting blocks

Depending on the WooCommerce version used, several product filtering and sorting blocks are available for use together with the Product Collection and Products (Beta) blocks:

  • Product Filters
  • Filter by Price
  • Filter by Attribute
  • Filter by Stock
  • Filter by Rating
  • Active Filters
  • Catalog Sorting
  • Pagination

These blocks are all incompatible with FacetWP. Don’t use these blocks, or remove them when they are added automatically. Use facets instead.

GenerateBlocks Query (v2) block unsupported “Query Type” settings

When using GenerateBlocks Pro, the Query (v2) block has a “Query Type” setting, for which only the “Post Query” option is supported. FacetWP cannot filter post meta or options.

Don’t use any Spectra Pro (Advanced) Loop Builder search, sort, filter and pagination blocks

Don't use any Spectra Pro (Advanced) Loop Builder search, sort, filter and pagination blocks. Remove them and use facets instead.
Don’t use any Spectra Pro (Advanced) Loop Builder search, sort, filter and pagination blocks. Remove them andoes not work with a separate Pagination block d use facets instead.

Depending on the block variation used, the Spectra Pro v1.2.0+ (Advanced) Loop Builder block inserts its own set of filtering, sorting, searching, and pagination child blocks:

  • Category – Filter
  • Sorting – Filter
  • Search – Filter
  • Reset – Filter
  • Pagination

These blocks are all incompatible with FacetWP. Don’t use these blocks, or remove them (including their Container blocks) when they are added automatically. Use facets instead.

The Otter Blocks Posts block has an “Enable Featured Post” setting. This setting is incompatible with FacetWP’s Pager facet pagination: it adds the same featured post to each page of the listing, and also counts it towards the number of posts per page.

Using a core Accordion block with FacetWP

WordPress 6.9 introduced a new core Accordion block.

As long as you use this block outside of FacetWP-enabled listing templates and listing blocks, the accordion will work just fine. You could, for example, add your facet shortcodes in a Shortcode block or facet blocks, inside an Accordion block.

However, using an Accordion block within a listing template or listing block, for example to store items within the retrieved post items, is problematic. This is because every script that runs on post elements in a listing needs to be re-initialized after an AJAX refresh (which happens when using facets).

Normally, this re-triggering can easily be accomplished by re-initializing the script(s) within the facetwp-loaded hook, which fires after each refresh. The problem however with the Accordion block is that it uses WP’s Interactivity API, which works with React and its virtual DOM. This makes it impossible to re-initialize the Accordion block’s script after FacetWP’s AJAX refresh.

To make a long story short: don’t use an Accordion block (or any other existing or future block that uses the Interactivity API, like the AJAX-enabled “Add to Cart Button” block) within a FacetWP-enabled listing template (or listing block).

Using the “Add to Cart Button” block in the Product Collection block

The 'Add to Cart Button' block only works after a facet refresh with the 'AJAX add to cart buttons' setting disabled.
The “Add to Cart Button” block only works after a facet refresh with the “AJAX add to cart buttons” setting disabled.

If you are using the Blocks add-on, the default “Add to Cart Button” block within the WooCommerce Product Collection block will not work after FacetWP’s AJAX refresh, if the “Enable AJAX add to cart buttons on archives” setting (under WooCommerce > Settings > Products > Add to cart behaviour) is enabled.

This issue unfortunately does not have a simple fix: at the time of writing, there is no way to re-trigger the block’s JavaScript after a facet refresh, because it is using the WP Interactivity API. You can follow this GitHub issue for updates on a possible fix in a future WooCommerce version.

So the only way to get the default “Add to Cart Button” block working after a facet refresh is to disable the “Enable AJAX add to cart buttons on archives” setting.

If you don’t like a non-AJAX add-to-cart button, you could find and use a third-party “add to cart” block that does not use the WP Interactivity API, and retrigger its JavaScript using the facetwp-loaded hook.

Or, the most practical solution, is to use a custom shortcode to render the “regular” (classic/non-block) WooCommerce add-to-cart button in the Product Collection block:

Render the classic add-to-cart button in the Product Collection block with a custom shortcode

A solution to the above issues with the default “Add to Cart Button” block in the Product Collection block, is to create a custom shortcode to render the “regular” (classic/non-block) add-to-cart button instead. You can do this as follows.

First, add the following snippet to your (child) theme’s functions.php. This will create a custom [dynamic-add-to-cart] shortcode that outputs WooCommerce’s “regular” “add-to-cart” shortcode.

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_shortcode( 'dynamic-add-to-cart', function() { $product_id = get_the_ID(); if ( ! $product_id ) { return ''; } return do_shortcode( '[add_to_cart id="' . $product_id . '"]' ); });

You’d expect that adding this shortcode in a Shortcode block, within the Product Collection block’s Product Template block, would now output the add to cart button. However, there is a longstanding bug that prevents shortcodes in Query Loop type blocks from having access to the post ID with get_the_ID().

Using a Meta Field Block within a Product Collection block to output a custom shortcode.
Using a Meta Field Block within a Product Collection block to output a custom shortcode.
How to use a Meta Field Block to output a custom shortcode.
How to use a Meta Field Block to output a custom shortcode.

Luckily, this can be solved by installing the Meta Field Block plugin. Add a Meta Field Block within the Product Collection block’s Product Template block, as shown in the image on the right.

In the block’s settings, under “Field Type” select “Dynamic field”.

Then, paste the custom shortcode [dynamic-add-to-cart] into the “Field Name” field. The settings should look like the image on the right.

After saving the page, the regular “add-to-cart button will now work, both with and without the “Enable AJAX add to cart buttons on archives” setting (under WooCommerce > Settings > Products > Add to cart behaviour) enabled. It will also preserve facet selections when clicking the button.

Fix issues with facets and listings in block patterns

If you are using facets or Listing Builder listings in block pattern template files, you may run into the issue that your facets/listings don’t render in the front-end, and disappear in the block editor.

The cause is the way WordPress (currently) processes shortcodes and PHP code contained in block patterns templates, in the editor. The exact behaviour can be erratic and confusing, and depends on:

  • in which view (the Visual editor or the Code editor) the pattern was added and saved;
  • if the editor was switched between these views.

In most situations, the shortcode or PHP contained in the pattern template will be processed in the editor, and with that, converted to HTML. This does not work with facets and listings.

Using any of the following usual methods to render facets (or listings) in the pattern template will not work, and will trigger the above-described issues:

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

echo facetwp_display( 'facet', 'my_facet_name' ); // Or echo do_shortcode('[facetwp facet="my_facet_name"]');

The trick to get this working is to add the facet/listing as follows. Using this method, the facet/listing will render as a normal processed shortcode in the frontend, and as an unprocessed shortcode block in the block editor:

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

if ( ! is_admin() && ! ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { echo do_shortcode('[facetwp facet="my_facet_name"]'); } else { echo '<!-- wp:shortcode -->[facetwp facet="my_facet_name"]<!-- /wp:shortcode -->'; }

If using the above still leads to the same issues, try starting from a new fresh page/post, as in our tests this often fixed the issues.

Use a FacetWP-enabled custom WP_Query in a custom ACF block

To learn how to create a filterable custom WP_Query as an ACF Pro block, read this section on our Advanced Custom Fields page. Note that you don’t need the Blocks add-on to do this.

Changelog

0.3

0.2

  • Jan 5, 2024
  • New Added support for Stackable Posts block, and Stackable nested container block types
  • New Added support for Spectra Post Grid block, and Spectra nested container block types
  • New Added support for Spectra Pro Loop Builder block
  • New Added support for Otter Blocks Posts blocks and Otter Blocks nested container block types
  • Improved Added support for more Kadence Blocks nested container block types
  • Fixed Fixed issue with blocks running through `get_the_excerpt()`, and in Yoast SEO OpenGraph data and Twitter card data excerpt generation, causing duplicate FacetWP enabled queries
  • Updated Package.json, removed unused packages

0.1

  • Nov 15, 2023
  • New Initial release

See also

Last updated: March 23, 2026