Hooks and filters

Customize WPXFacets from your own code: change facet values, adjust indexing and search, and react to search results in the browser.

For developers. Every entry is generated from the plugin source.

Reference for WPXFacets 0.1.18

Every entry on this page is present in WPXFacets 0.1.18. Entries marked “Introduced in version 0.1.18” are new in that release. Where the introduction version is shown as unknown, the release that first included the entry has not been established. Check the plugin version you have installed before relying on an entry.

Introduction

WPXFacets offers three kinds of extension points:

  • Filters change a value WPXFacets is about to use and return it, such as the labels of facet values.
  • Actions tell your code that something happened. The listing action xfacets_after_product_search is observational: changing its argument changes nothing.
  • Browser events let theme and plugin scripts react to searches in the page, such as xfacets:results-updated.

Put PHP in a small site plugin or a must-use plugin (wp-content/mu-plugins), not in a theme you may replace. Hooks that change indexed data take effect when products are next synced.

Each entry lists which search engine it applies to. Managed search is the WPXFacets search service; the WordPress fallback serves listings from the WordPress database when managed search is off, unavailable or fails. A hook marked for one engine does not run on the other.

Product cards in WPXFacets results come from WooCommerce’s own content-product template, on page load and after each refinement, so WooCommerce’s product-loop hooks keep working on them. Those are WooCommerce hooks, not WPXFacets contracts.

Recipes

Rename facet values

Raw meta values such as yes and no make poor labels. xfacets_facet_values lets you replace the label of a value; counts, selections and swatches stay as the search engine returned them, and a value the shopper selected always stays visible.

add_filter(
	'xfacets_facet_values',
	function ( array $values, array $facet ) {
		// Only the facet that reads the `gift_wrap` meta field.
		if ( 'meta_field' !== $facet['source'] || 'gift_wrap' !== $facet['source_value'] ) {
			return $values;
		}

		// Fixed English labels. A translated callback must use the third argument's
		// `language` or `locale`, not the current WordPress locale.
		$labels = array(
			'yes' => 'Gift wrap available',
			'no'  => 'No gift wrap',
		);

		foreach ( $values as $index => $row ) {
			if ( isset( $labels[ (string) $row['slug'] ] ) ) {
				$values[ $index ]['label'] = $labels[ (string) $row['slug'] ];
			}
		}

		return $values;
	},
	10,
	2
);

This example supplies fixed English labels. To translate labels, use the language or locale of the third argument, $context: in a REST refinement the values are built before WordPress switches to the catalogue locale, so the current locale can be the wrong one. The same filter can reorder values or remove unselected ones, on page load and after every refinement, on both search engines.

Keep a meta key out of the managed index

Public product meta is indexed for managed search. xfacets_excluded_meta_keys removes an exact key, in addition to the built-in denylist for sensitive names.

add_filter(
	'xfacets_excluded_meta_keys',
	function ( array $keys ) {
		$keys[] = 'supplier_cost';

		return $keys;
	}
);

Products keep the old value in the index until they are synced again: run a full sync after adding the filter. The WordPress fallback reads the database and is not affected.

xfacets_search_bar_runtime_config changes Search Bar options in code, including ones without a setting such as recent searches. WPXFacets clamps every value afterwards, so out-of-range numbers are corrected.

add_filter(
	'xfacets_search_bar_runtime_config',
	function ( array $config ) {
		$config['show_recent']      = false;
		$config['completion_limit'] = 8;

		return $config;
	}
);

Update a custom product counter

Listen for xfacets:results-updated on document. It fires once per results container, so deduplicate on detail.requestId when the effect belongs to the whole listing. Zero matches are a normal update with detail.count 0.

let lastRequestId = null;

document.addEventListener( 'xfacets:results-updated', ( event ) => {
	// One event arrives per results container; act once per listing.
	if ( event.detail.requestId === lastRequestId ) {
		return;
	}
	lastRequestId = event.detail.requestId;

	const counter = document.querySelector( '.my-product-counter' );
	if ( counter ) {
		counter.textContent = 0 === event.detail.count
			? 'No products match'
			: event.detail.count + ' products';
	}
} );

Failed searches send xfacets:search-failed instead and leave the previous results in place.

PHP hooks (21)

Supported PHP hooks for integrations, in alphabetical order.

Fires after a storefront product listing was resolved and its facets hydrated.

PropertyValue
KindAction (no return value)
StabilityPublic
Search enginesManaged search, WordPress fallback
Runs onStorefront pages, REST requests
IntroducedIntroduced in version 0.1.18

Observational. Fires once per successful listing query of the Shop page, the results shortcode or block (page) and every REST refinement (rest), on managed search and on the WordPress fallback, after facet values and the best-effort Search Analytics step; zero matches still fire. It does not fire when both engines failed, nor for the facet-order visibility probe, Trending verification or autosuggest. Engine, fallback reason and language are recorded when the query ran, before xfacets_after_page_facets_query listeners. The argument is a copy: changing it changes nothing. It carries no search text, selections, product IDs, URL or internal identifiers. PHP does not run on page or edge cache hits, so this is not a page-view count. Callbacks run inside the storefront request: defer slow external calls.

Arguments

  1. $search (array): Listing summary.
    • $contract (int): 1.
    • $surface (string): page or rest.
    • $engine (string): managed or wordpress.
    • $fallback_reason (string): none, filter_mode, force_wp, http_error, transport_error or payload_error.
    • $count (int): Matching products, at least 0.
    • $count_relation (string): eq (exact), gte (lower bound) or unknown.
    • $page (int): 1-based page.
    • $per_page (int): Page size; -1 when the caller asked for every product.
    • $sort (string): Effective <order_by>-<order>, for example price-asc.
    • $language (string): Canonical catalogue language the engine searched with, ” when it had none.
    • $search_active (bool): Whether a keyword (Search Bar or Search facet) applied.

xfacets_allowed_meta_keys

Filters the protected (underscore-prefixed) meta keys that may be indexed.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search
Runs onProduct sync, wp-admin
IntroducedIntroduction version unknown

Protected meta is skipped unless its exact key is listed here; the sensitive-key denylist and xfacets_excluded_meta_keys still win. The same list decides whether a change to a protected key queues the product for incremental sync and whether the key may back a swatch mapping. The plugin’s WooCommerce integration adds its own keys through this filter. Changes take effect on each product’s next sync.

Arguments

  1. $allowed_meta_keys (string[]): Allowed protected keys. Default array( '_thumbnail_id' ).
  2. $indexable (\XFacets\Indexables\XFacets_Product_Indexable): Current indexable.

Returns string[]: Allowed protected keys.

xfacets_defer_sync_on_save

Filters whether sync-on-save is suspended for the current request.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Read at every queueing and flush entry point, so a script can toggle it partway through a request. The XFACETS_DISABLE_SYNC constant, when true, wins before the filter runs. The result is cast to bool.

Arguments

  1. $deferred (bool): Whether to skip queueing and flushing. Default false.

Returns bool: Whether sync-on-save is suspended.

xfacets_excluded_meta_keys

Filters the exact meta keys that are never indexed.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search
Runs onProduct sync, wp-admin
IntroducedIntroduction version unknown

Checked for every meta key after the built-in sensitive substring denylist (password, token, _billing_ and similar), which always applies. The same check decides whether a meta key may back a swatch mapping. Changes take effect on each product’s next sync.

Arguments

  1. $keys (string[]): Exact meta keys to exclude. Default empty.

Returns string[]: Exact meta keys to exclude.

xfacets_facet_usage_events_rate_limit

Filters the per-visitor request budget of one public REST route.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onREST requests
IntroducedIntroduction version unknown

The hook name is fixed by the route’s controller when it constructs this guard. Read once per request, when the route spends the caller’s budget. The result is cast to an array and clamped: limit 1–600 requests per window of 10–300 seconds; a missing key keeps the route default.

This name: Facet usage events route. Default 30 requests per 60 seconds.

Arguments

  1. $policy (array): Route defaults: limit and window in seconds.
  2. $request (mixed): Current REST request.

Returns array: Policy.

Filters whether this request’s visitor may be counted by category facet usage.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onREST requests
IntroducedIntroduction version unknown

Read by the public facet usage events endpoint for each submitted batch. Return false to refuse a visitor your consent tool has not cleared; the browser then ends its session. Only a refusal is effective: the filter does not run when the WP Consent API already refused, and any value other than false keeps the incoming answer.

Arguments

  1. $consent (bool): The WP Consent API’s statistics answer, or true when it is absent.

Returns bool: False to refuse.

xfacets_facet_values

Filters the value rows of one refinement-list facet before they reach the storefront.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search, WordPress fallback
Runs onStorefront pages, REST requests
IntroducedIntroduced in version 0.1.18

Runs once per refinement-list facet (checkbox, radio and rating displays) of every storefront listing query: the Shop page, the results shortcode or block and every REST refinement, on managed search and on the WordPress fallback, after rows were built and swatches were added. Range and Search facets, the facet-order visibility probe, Trending verification and autosuggest never run it. Rows are matched back to the originals by slug: only a valid label (a string, plain text after tags are stripped, at most 200 characters) is taken from a callback, and unknown, duplicate or malformed rows are dropped. Selected or excluded rows the callback removed are appended again in their original order. A non-array return keeps the original rows and warns once per request. Exceptions are not caught. Keep callbacks deterministic for their arguments and do not personalize them. Refinements are public GET requests, but that does not make their responses safe to cache by URL: the product HTML they carry depends on the shopper’s tax and currency context. $context['language'] and $context['locale'] are the ones the engine executed the listing with; in a REST refinement rows are built before the product HTML switches to that locale, so translate with them, not the current locale.

Arguments

  1. $original (array): Ordered list of value rows.
    • Each item (array):
      • $slug (int|string): Value identity; numeric values may be integers.
      • $label (mixed): Display label.
      • $count (int|string): Matching products, as the engine returned it.
      • $swatch (array): Optional swatch (type color or image).
  2. $facet (array): Read-only description of the facet.
    • $id (int): Facet ID.
    • $form_id (int): Filter form ID.
    • $slug (string): Facet slug (the URL parameter after the prefix).
    • $type (string): Behavioral type, always refinement_list here.
    • $display_type (string): checkbox, radio or rating.
    • $source (string): Value source, for example product_attribute or meta_field.
    • $source_value (string): Source field, for example pa_color or a meta key.
  3. $context (array): Listing context.
    • $contract (int): 1.
    • $surface (string): page or rest.
    • $engine (string): managed or wordpress.
    • $language (string): Canonical catalogue language the engine searched with, ” when it had none.
    • $locale (string): Catalogue locale of that language, ” when unavailable.
    • $search_active (bool): Whether a keyword (Search Bar or Search facet) applied.

Returns array: Ordered list of value rows.

xfacets_search_analytics_budget_policy

Filters the Search Analytics write budget.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onStorefront pages
IntroducedIntroduction version unknown

Read each time a search event is about to be recorded. The result is clamped: caller_limit 1–300 per caller_window of 10–300 seconds, and daily_write_limit 100–1,000,000.

Arguments

  1. $policy (array): caller_limit 30, caller_window 60 and daily_write_limit 50000.

Returns array: Policy.

xfacets_search_analytics_should_record

Filters whether an otherwise eligible search is recorded by Search Analytics.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onStorefront pages
IntroducedIntroduction version unknown

Runs after every built-in eligibility check passed, on a first-paint storefront search. It deliberately receives no search terms. Only an exact true allows recording.

Arguments

  1. $allowed (bool): Whether to record. Default true.

Returns bool: Exactly true to record.

xfacets_search_bar_results_url

Filters the URL the Search Bar form submits to.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onStorefront pages
IntroducedIntroduction version unknown

Runs when the Search Bar renders (shortcode, block or editor preview). The default is the current-language Search results page, else the WooCommerce Shop page. The result is cast to a string and passed through esc_url_raw(); an empty URL renders a configuration message for editors and nothing for visitors.

Arguments

  1. $url (string): Results URL.
  2. $status (array): Results page status (configured, valid, page_id, url, fallback, warning, …).

Returns string: Results URL.

xfacets_search_bar_runtime_config

Filters the runtime Search Bar configuration.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onStorefront pages, REST requests
IntroducedIntroduction version unknown

Read when the Search Bar renders and by the autosuggest endpoint. Every key is sanitized and clamped after the filter: minimum_characters 1–10, completion_limit 1–12, product_limit 1–10, featured_limit 0–8, query_ttl 5–300 and zero_ttl 30–3600 seconds. The plugin’s Polylang integration consumes this filter.

Arguments

  1. $config (array): Configuration: stored settings plus featured_limit 4, show_correction and show_recent true, query_ttl 30 and zero_ttl 300.

Returns array: Configuration.

xfacets_search_fields

Filters the weighted Text paths of one search input in managed queries.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search
Runs onStorefront pages, REST requests, wp-admin
IntroducedIntroduction version unknown

Runs when the managed query builder handles the Search Bar keyword or one Search facet. Exact and Prefix fields are not part of this list and cannot be added through it. An empty or non-array return keeps the original paths. The WordPress fallback uses xfacets_wp_search_fields instead.

Arguments

  1. $paths (string[]): path^weight expressions for the input’s Text fields.
  2. $facet (\XFacets\Models\Facets\XFacets_Facet|null): The Search facet, or null for the Search Bar.
  3. $context (array): surface (search_bar or facet) and canonical fields.

Returns string[]: path^weight expressions.

xfacets_search_products_circuit_breaker

Filters the backend circuit-breaker policy of one public REST route.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onREST requests
IntroducedIntroduction version unknown

The hook name is fixed by the route’s controller when it constructs this guard. Read whenever the route evaluates its circuit breaker: backend failures and slow responses. The result is cast to an array and clamped: failures 1–10, cooldown 5–300 seconds, slow_seconds 0.1–10; a missing key keeps the route default.

This name: Product refinement route. Defaults: 3 failures, 30 s cooldown, 2.5 s slow threshold.

Arguments

  1. $policy (array): Route defaults: failures, cooldown and slow_seconds.

Returns array: Policy.

xfacets_search_products_rate_limit

Filters the per-visitor request budget of one public REST route.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onREST requests
IntroducedIntroduction version unknown

The hook name is fixed by the route’s controller when it constructs this guard. Read once per request, when the route spends the caller’s budget. The result is cast to an array and clamped: limit 1–600 requests per window of 10–300 seconds; a missing key keeps the route default.

This name: Product refinement route. Default 90 requests per 60 seconds.

Arguments

  1. $policy (array): Route defaults: limit and window in seconds.
  2. $request (mixed): Current REST request.

Returns array: Policy.

xfacets_search_suggest_circuit_breaker

Filters the backend circuit-breaker policy of one public REST route.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onREST requests
IntroducedIntroduction version unknown

The hook name is fixed by the route’s controller when it constructs this guard. Read whenever the route evaluates its circuit breaker: backend failures and slow responses. The result is cast to an array and clamped: failures 1–10, cooldown 5–300 seconds, slow_seconds 0.1–10; a missing key keeps the route default.

This name: Autosuggest route. Defaults: 3 failures, 30 s cooldown, 1.5 s slow threshold.

Arguments

  1. $policy (array): Route defaults: failures, cooldown and slow_seconds.

Returns array: Policy.

xfacets_search_suggest_rate_limit

Filters the per-visitor request budget of one public REST route.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesNot tied to a search engine
Runs onREST requests
IntroducedIntroduction version unknown

The hook name is fixed by the route’s controller when it constructs this guard. Read once per request, when the route spends the caller’s budget. The result is cast to an array and clamped: limit 1–600 requests per window of 10–300 seconds; a missing key keeps the route default.

This name: Autosuggest route. Default 120 requests per 60 seconds.

Arguments

  1. $policy (array): Route defaults: limit and window in seconds.
  2. $request (mixed): Current REST request.

Returns array: Policy.

xfacets_sync_batch_size

Filters the batch size of one full-sync session.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Read once when a session starts, so a driver can override the stored setting for one run (wp xfacets index rebuild --batch-size=50 on a memory-starved host) without writing to xfacets_settings. The result is cast to int with a minimum of 1. The product transport still splits each batch into smaller gateway write requests.

Arguments

  1. $limit (int): Items per batch. Default: the stored setting, else 300.
  2. $driver (string): Driver starting the session: ajax or cli.

Returns int: Items per batch.

xfacets_sync_taxonomies

Filters the taxonomies whose terms are indexed with one product.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Runs per product during document preparation. The default is every public or publicly queryable taxonomy of the post type. After the filter, names are converted to taxonomy objects and unknown taxonomies are dropped. The plugin’s WooCommerce integration consumes this filter. Takes effect on the product’s next sync.

Arguments

  1. $selected_taxonomies (array<\WP_Taxonomy|string>): Taxonomy objects or names.
  2. $post (\WP_Post): Product post.

Returns array<\WP_Taxonomy|string>: Taxonomy objects or names.

xfacets_term_fanout_limit

Filters how many products a single term edit may queue for incremental sync.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search
Runs onProduct sync, wp-admin
IntroducedIntroduction version unknown

Read when a term is edited, after counting its products. Above the limit the inline work is declined and the index is marked stale for a full reindex. The result is cast to int; zero or less disables the cap.

Arguments

  1. $limit (int): Maximum affected products processed inline. Default 5000.
  2. $taxonomy (string): Taxonomy of the edited term.

Returns int: Maximum affected products.

xfacets_url_facet_prefix

Filters the URL query-variable prefix of facet, page and sort parameters.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesManaged search, WordPress fallback
Runs onEvery request that reads it
IntroducedIntroduction version unknown

Read on every request that builds or reads facet URLs, in PHP and, through xfacets_search_data.facets_prefix, in the browser. Facet objects read it once, when they are constructed. The value is not validated: an empty prefix makes facet slugs collide with WordPress query variables such as page, paged and s.

Arguments

  1. $prefix (string): Prefix. Default f_.

Returns string: Prefix.

xfacets_wp_search_fields

Filters the WordPress fallback descriptors of one search input.

PropertyValue
KindFilter (return a value)
StabilityPublic
Search enginesWordPress fallback
Runs onStorefront pages, REST requests
IntroducedIntroduction version unknown

Runs when the WordPress fallback builds the keyword clause of the Search Bar query or of one Search facet. An empty or non-array return keeps the original descriptors; descriptor types and modes are validated again when the SQL is built, and unknown types are skipped. The managed engine uses xfacets_search_fields instead.

Arguments

  1. $descriptors (array): post_field, meta or taxonomy descriptors with weight and match.
  2. $context (array): surface (search_bar or facet), canonical fields and facet.

Returns array: Descriptors.

Browser events (6)

Native events from WPXFacets are CustomEvent objects dispatched on each .xfacets-search-results element. They bubble to document, cannot be cancelled, and carry a frozen detail object of plain values: detail.contract, detail.requestId, detail.source, then detail.count, detail.page, detail.perPage and detail.sort for an update, or detail.code and detail.retryAfter for a failure. An update fires after the product grid was replaced and the filters re-rendered, and once on page load with requestId 0. A response that a newer search replaced fires nothing. These values are what the browser requested; use xfacets_after_product_search for what the server executed. The older jQuery events still fire as before. Some entries are things your code provides — a wp.hooks filter or an event you dispatch — rather than notifications from WPXFacets; their kind says which.

xfacets-facets.facets-loaded

Fired on every .xfacets-search-facets element after a filter form app hydrated its facets from the first-paint data.

PropertyValue
KindjQuery event (WPXFacets triggers it)
StabilityPublic
IntroducedIntroduction version unknown

Limits

  • Namespaced jQuery event with no arguments; addEventListener cannot receive it.
  • Hydration runs once per filter form app, so a page with several forms fires it once per form on every element.

xfacets-facets.search-done

Fired on every .xfacets-search-results element when a product refinement request finished.

PropertyValue
KindjQuery event (WPXFacets triggers it)
StabilityPublic
IntroducedIntroduction version unknown

Limits

  • Fires on failure as well as on success; there is no payload saying which, and none with count, page or sort.
  • Fires after the grid HTML was replaced and before Vue re-renders the facets; a superseded response fires nothing.
  • Namespaced jQuery event; addEventListener cannot receive it.

xfacets:results-updated

Fired on every .xfacets-search-results element after a successful search replaced the product grid HTML and Vue re-rendered the facets.

PropertyValue
KindDOM event (WPXFacets dispatches it)
StabilityPublic
IntroducedIntroduced in version 0.1.18

Fires for refinements, sorting, paging, Back/Forward and Clear all, including searches with zero matches. On page load it fires once, after the first Vue render, with source hydration and requestId 0 — unless the page needs a follow-up search to complete its facets, in which case that search’s update is the first event, or a newer search started first. A response superseded by a newer search fires nothing, also when it is superseded while Vue renders. Bubbles to document; not cancelable.

FieldTypeMeaning
detail.contractnumberAlways 1.
detail.requestIdnumberPer-page search sequence number; 0 for the page-load notification.
detail.sourcestringhydration, manual, search, sort, page, popstate, clear_all or programmatic.
detail.countnumberMatching products the response reported, a nonnegative integer.
detail.pagenumberRequested page, a positive integer.
detail.perPagenumberRequested page size; -1 would mean every product.
detail.sortstringRequested sort token, for example price-asc; an unsupported token reads as relevance.

Limits

  • Client request metadata: server-side changes made through xfacets_page_request are not reflected.
  • One event per results container; deduplicate on requestId for once-per-listing effects.
  • No search text, selections, URL, product or customer identifiers.

xfacets:search-failed

Fired on every .xfacets-search-results element when a current search failed, after the existing error message. The previous product grid stays in place and no xfacets:results-updated follows.

PropertyValue
KindDOM event (WPXFacets dispatches it)
StabilityPublic
IntroducedIntroduced in version 0.1.18

Also fires, with request_failed, when a successful response carried no usable results fragment, because the grid was not replaced. A failure superseded by a newer search fires nothing. Bubbles to document; not cancelable.

FieldTypeMeaning
detail.contractnumberAlways 1.
detail.requestIdnumberPer-page search sequence number.
detail.sourcestringmanual, search, sort, page, popstate, clear_all, hydration or programmatic.
detail.codestringMachine reason, for example rate_limited or search_unavailable; request_failed otherwise.
detail.retryAfternumberSeconds the server asked to wait, a nonnegative integer; 0 when none.

Limits

  • No error text or response body.
  • A response that cannot be read at all (no facets object) rejects the search before any event, as the legacy signal does not fire either.

Lets a consent integration refuse category facet usage collection for this visitor.

PropertyValue
Kindwp.hooks filter (your code adds it)
StabilityPublic
IntroducedIntroduction version unknown

Limits

  • Receives true; returning exactly false, or throwing, refuses. It cannot overrule a refusal of the WP Consent API.
  • The facets script declares the core wp-hooks dependency, so wp.hooks is loaded before it wherever WordPress prints the script.

Dispatched on document by a site’s consent tool when the visitor changes the choice; collection then starts or stops according to the current consent state.

PropertyValue
KindDOM event (your code dispatches it)
StabilityPublic
IntroducedIntroduction version unknown

Limits

  • Only signals a change; the state itself is read from window.xfacets_facet_usage_consent, the xfacets_facet_usage_consent filter and the WP Consent API.

Advanced PHP hooks (30)

These hooks work, but expose engine-specific structures, mutable internal objects or operator settings. Read each caveat; some change only one search engine, and some can break listings or indexing when misused. They are specialist extension points, without a promise that their signatures stay stable.

Show the 30 advanced hooks

xfacets_after_page_facets_query

Fires after the product query of a storefront listing, before facet values are hydrated.

PropertyValue
KindAction (no return value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onStorefront pages, REST requests
IntroducedIntroduction version unknown

Runs for the Shop page, the results shortcode or block and every REST refinement, on either backend, and before Search Analytics records the response. The result object is mutable and facets and analytics read it afterwards. The plugin’s own WooCommerce loop setup is attached to this action, so removing all its callbacks leaves the product grid without totals.

Arguments

  1. $result (\XFacets\Models\CacheServers\XFacets_Cache_Server_Res): Query result.

xfacets_catalog_language_adapter

Filters the catalogue-language adapter.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onEvery request that reads it
IntroducedIntroduction version unknown

Runs on every catalogue-language resolution: storefront and REST queries, sync and admin. The detected value is site, polylang, wpml or ambiguous (both plugins active). After the filter, ambiguous and any value other than site, polylang, wpml or custom return an error instead of a language.

Arguments

  1. $adapter (string): Detected adapter.

Returns string: Adapter name.

xfacets_catalog_language_analyzer_profile

Filters the analyzer profile of one catalogue language while the language manifest is built.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync, wp-admin
IntroducedIntroduction version unknown

Return null to derive the profile from the locale. Any other value is explicit and is validated without fallback: an unknown profile fails the manifest build. Takes effect on the next full sync.

Arguments

  1. $explicit_profile (string|null): Explicit profile from the language definition, or null.
  2. $language (string): Canonical language key.
  3. $locale (string): Normalized source locale.
  4. $adapter (string): Catalogue-language adapter.

Returns string|null: Explicit profile, or null to derive it.

xfacets_catalog_language_definitions

Filters the active catalogue-language definitions.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onEvery request that reads it
IntroducedIntroduction version unknown

Read wherever languages are resolved or listed: storefront and REST queries, sync and admin. Each entry may contain only language, locale and optionally analyzer_profile; the manifest builder keeps a strict projection and drops provider metadata.

Arguments

  1. $definitions (array): Provider definitions.
  2. $adapter (string): Adapter name.

Returns array: Definitions.

xfacets_catalog_language_eligible_query_args

Filters the WP_Query arguments of the full-sync eligible product population.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Read during the full-sync language preflight. The resulting product count is what the language manifest expects the sync to deliver. The result is only cast to an array.

Arguments

  1. $args (array): Full-catalogue preflight query arguments.

Returns array: Query arguments.

xfacets_catalog_language_page_id

Filters the current-language translation of a configured page, such as the Search results page.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesNot tied to a search engine
Runs onStorefront pages
IntroducedIntroduction version unknown

Runs when the Search Bar renders and resolves its results URL. The result must be an integer of at least 1; anything else fails closed as an unavailable translation.

Arguments

  1. $translated (int|null): Provider translation ID, or null.
  2. $page_id (int): Configured page ID.
  3. $context (array): Validated catalogue-language context.

Returns int|null: Translated page ID.

xfacets_catalog_language_product_query_args

Filters the WP_Query arguments of one catalogue language’s product corpus.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onProduct sync, Storefront pages, REST requests
IntroducedIntroduction version unknown

Used by the full sync and by the WordPress fallback. Registering any callback (has_filter()) switches the fallback’s language restriction from an EXISTS clause to an explicit product ID list built from this query. The result is only cast to an array.

Arguments

  1. $args (array): Corpus query arguments.
  2. $language (string): Canonical language key.
  3. $adapter (string): Adapter name.

Returns array: Query arguments.

xfacets_catalog_product_languages

Filters the catalogue-language attribution of one product.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Runs for full-sync language attribution and for incremental writes. A scalar is the normal case; an array is accepted only so that an ambiguous custom attribution is detected and rejected instead of being collapsed. The manifest builder validates the result.

Arguments

  1. $candidates (mixed): Provider language candidate or candidates.
  2. $post_id (int): Product post ID.
  3. $adapter (string): Adapter name.

Returns mixed: Language candidate or candidates.

xfacets_current_catalog_language

Filters the current catalogue-language candidate.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onEvery request that reads it
IntroducedIntroduction version unknown

Runs on every storefront and REST query and wherever the current language is resolved. The result is normalized and must match an active definition, otherwise resolution fails. The plugin’s facet-order visibility probe also adds a callback at PHP_INT_MAX while it runs.

Arguments

  1. $candidate (string): Provider language candidate.
  2. $adapter (string): Adapter name.

Returns string: Language candidate.

xfacets_default_catalog_language

Filters the default catalogue-language candidate.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onEvery request that reads it
IntroducedIntroduction version unknown

Read wherever the default language is resolved: storefront, sync, synonyms and admin. The result is normalized and must match an active definition, otherwise resolution fails.

Arguments

  1. $candidate (string): Provider default-language candidate.
  2. $adapter (string): Adapter name.

Returns string: Language candidate.

xfacets_es_prepare_child

Filters the nested document of one published variation.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Runs once per published variation of a variable product during document preparation. The return value is not validated; it is appended to the children list as returned.

Arguments

  1. $child (array): Prepared variation document.
  2. $variation (\WC_Product_Variation): Variation.
  3. $product (\WC_Product): Parent variable product.
  4. $indexable (\XFacets\Indexables\XFacets_Product_Indexable): Current indexable.

Returns array: Variation document.

xfacets_es_prepare_children

Filters the nested variation documents of one variable product.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Runs after every variation has passed xfacets_es_prepare_child. The result is only cast to an array. children_count in the product document is computed from this filtered list, before xfacets_es_prepare_document runs. Products that are not variable never reach this filter.

Arguments

  1. $children (array[]): Variation documents.
  2. $product (\WC_Product): Parent variable product.
  3. $indexable (\XFacets\Indexables\XFacets_Product_Indexable): Current indexable.

Returns array[]: Variation documents.

xfacets_es_prepare_document

Filters the complete managed-index document of one product before it is sent to the gateway.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Last step of document preparation for full and incremental sync, after the meta denylist and the children filters. The call site does not validate the return value: the gateway client rejects the whole write request unless every document is a non-list array whose integer ID, post_id and post_parent equal the product ID. Data added here bypasses the meta denylist and is stored in the managed index; the WordPress fallback never reads it. Takes effect on the product’s next sync. The plugin’s WooCommerce Product Bundles integration consumes this filter.

Arguments

  1. $post_args (array): Prepared document.
  2. $post (\WP_Post): Product post.
  3. $indexable (\XFacets\Indexables\XFacets_Product_Indexable): Current indexable.

Returns array: Document to index.

xfacets_facet_default_order_changed

Fires after a filter form’s default facet order has been replaced by an applied suggestion.

PropertyValue
KindAction (no return value)
StabilityAdvanced
Search enginesNot tied to a search engine
Runs onwp-admin
IntroducedIntroduction version unknown

Runs in wp-admin when a merchant applies the suggested default order and the conditional write committed. It does not fire when the order is unchanged or the write lost a concurrent edit.

Arguments

  1. $form_id (int): Filter form ID.

xfacets_facet_order_changed

Fires after the stored facet order of one category scope has changed.

PropertyValue
KindAction (no return value)
StabilityAdvanced
Search enginesNot tied to a search engine
Runs onwp-admin
IntroducedIntroduction version unknown

Runs in wp-admin after apply, reorder, pin, move, unpin or restore, only when the stored entry actually changed, so page caches of that category can be purged.

Arguments

  1. $category_id (int): product_cat term ID.
  2. $form_id (int): Filter form ID.
  3. $lang (string): Catalogue-language key of the scope.

xfacets_gateway_search_fields

Filters the Search Bar fields sent with a managed autosuggest request.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onREST requests
IntroducedIntroduction version unknown

Runs for each autosuggest request served by the managed gateway. Every returned field is validated again through the field registry; a non-array or empty result, or any invalid field, makes the request fail with xfacets_search_bar_fields_unavailable.

Arguments

  1. $mapped (array): Semantic field descriptors.
  2. $config (array): Stored search configuration.

Returns array: Semantic field descriptors.

xfacets_indexable_product_types

Filters the post types whose published posts are indexable products.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onProduct sync, Storefront pages, REST requests
IntroducedIntroduction version unknown

Despite the name, the value is a list of post types, not WooCommerce product types. It is read by is_indexable(), the full-sync eligible population, the per-language sync corpus and the WordPress fallback’s catalogue-language clause. Root documents are only built for the product post type, so adding a post type has no effect; removing product empties indexing and the fallback’s catalogue-language corpus. The result is only cast to an array.

Arguments

  1. $post_types (string[]): Post types. Default array( 'product' ).

Returns string[]: Post types.

xfacets_is_indexable

Filters whether one product post is indexable.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Runs in is_indexable(), which every index write path (full-sync batches, incremental sync, wp xfacets index item) applies after resolving variations to their parent. The default is true for a published post of an indexable post type. The return value is not cast to bool. The full-sync eligible population and per-language counts do not apply this filter, so returning false for a product they count can fail the full sync’s count check instead of excluding the product. The WordPress fallback never applies it.

Arguments

  1. $is_indexable (bool): Whether the product is indexable.
  2. $post (\WP_Post): Product post.

Returns bool: Whether the product is indexable.

xfacets_owns_catalog_query

Filters whether XFacets serves the catalog listing on this request.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onStorefront pages
IntroducedIntroduction version unknown

Read by the Shop query takeover (posts_pre_query), the listing wrappers and the pagination rewrite. The default is true on the Shop page and on pages rendering XFacets results. The seam for a site that scopes an archive itself, for example by pinning a facet value through a rewrite rule: returning true on an archive whose term is not pinned shows the full catalog. The result is cast to bool.

Arguments

  1. $owns (bool): Result of the built-in detection.

Returns bool: Whether XFacets serves the listing.

xfacets_page_request

Filters the internal request object of a storefront listing before the backend is chosen.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search, WordPress fallback
Runs onStorefront pages, REST requests
IntroducedIntroduction version unknown

Runs for the Shop page, the results shortcode or block and every REST refinement. Callbacks receive the mutable internal request, including the raw keyword, force_wp, facets and the analytics candidate; the WordPress fallback ignores the managed-only filter, query and aggs members. Return the same object or another XFacets_Cache_Server_Req (a subclass included). Any other return keeps the original object, with the changes callbacks already made to it, and warns once per request.

Arguments

  1. $req (\XFacets\Models\CacheServers\XFacets_Cache_Server_Req): Internal, mutable request object.

Returns \XFacets\Models\CacheServers\XFacets_Cache_Server_Req: Request object.

xfacets_resolve_search_field_es_path

Filters the managed-index field path of a search field whose source is not built in.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onStorefront pages, REST requests
IntroducedIntroduction version unknown

Reached only for extension sources that passed validation, when managed queries and suggestions resolve their fields. Any non-empty string is accepted as the path; there is no path allowlist, and the gateway’s Query DSL policy is the only bound. An empty or non-string result leaves the field unresolved.

Arguments

  1. $path (string): Field path. Default empty.
  2. $source (string): Semantic source identifier.
  3. $source_value (string): Source value.
  4. $registry (\XFacets_Search_Field_Registry): Registry.

Returns string: Field path.

xfacets_resolve_search_field_wp_descriptor

Filters the WordPress fallback descriptor of a search field whose source is not built in.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesWordPress fallback
Runs onStorefront pages, REST requests
IntroducedIntroduction version unknown

Reached only for extension sources that passed validation, when the WordPress fallback resolves its keyword fields. A non-array result leaves the field unresolved; descriptor types and modes are validated again when the SQL is built, and unknown types are skipped.

Arguments

  1. $descriptor (null): Always null.
  2. $source (string): Semantic source identifier.
  3. $source_value (string): Source value.
  4. $registry (\XFacets_Search_Field_Registry): Registry.

Returns array|null: Descriptor.

xfacets_search_bar_is_available

Filters whether the Search Bar is available.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onStorefront pages, REST requests, wp-admin
IntroducedIntroduction version unknown

Gates the shortcode, the block, the editor preview, the admin tab and the autosuggest endpoint. The default is true only when managed Elasticsearch serves products and the transport supports suggestions. Returning true does not add a fallback; it only stops the gating. The result is cast to bool.

Arguments

  1. $available (bool): Result of the built-in availability check.

Returns bool: Whether the Search Bar is available.

xfacets_search_bar_languages

Filters the languages the Search Bar may store and serve.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesNot tied to a search engine
Runs onStorefront pages, REST requests, wp-admin
IntroducedIntroduction version unknown

Read by the Search Bar admin editor, its stored configuration, the autosuggest endpoint and the Trending allowlist. Values are normalized and de-duplicated, and the list is never empty. It must stay an allowlist: the language is part of the suggest response cache key.

Arguments

  1. $languages (string[]): Normalized locales. Default: the site locale.

Returns string[]: Locales.

xfacets_search_field_source_values

Filters the selectable values of one search-field source in the Fields editors.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesNot tied to a search engine
Runs onwp-admin
IntroducedIntroduction version unknown

Read in wp-admin when the editors build their value catalogue. Meta fields have no list: their key is typed by the administrator. The result is cast to a list.

Arguments

  1. $values (array): Value definitions.
  2. $source (string): Semantic source identifier.
  3. $registry (\XFacets_Search_Field_Registry): Registry.

Returns array: Value definitions.

xfacets_search_field_sources

Filters the semantic search-field sources offered by the Fields editors.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesNot tied to a search engine
Runs onwp-admin
IntroducedIntroduction version unknown

Read when the Search Bar and Search facet editors load in wp-admin. The result is cast to a list. A source added here also needs xfacets_validate_search_field, xfacets_resolve_search_field_es_path and xfacets_resolve_search_field_wp_descriptor callbacks, otherwise it is rejected on save and cannot resolve at query time.

Arguments

  1. $sources (array): Source definitions (value, label, value_mode, matches).
  2. $registry (\XFacets_Search_Field_Registry): Registry.

Returns array: Source definitions.

xfacets_search_query_dsl

Filters the final Elasticsearch _search body immediately before managed-gateway transport.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onStorefront pages, REST requests, wp-admin
IntroducedIntroduction version unknown

Managed search only: it is not applied when the WordPress fallback serves, whatever the reason (configuration, force-wp, gateway or payload error). It also runs for the admin Trending verification. A non-array return keeps the generated body. The gateway still enforces its fixed target and bounded Query DSL policy. A callback can remove the catalog-visibility post_filter; that is unsupported.

Arguments

  1. $cache_server_args (array): Generated Query DSL body.
  2. $req (\XFacets\Models\CacheServers\XFacets_Cache_Server_Req): Internal, mutable request object.

Returns array: Query DSL body.

xfacets_search_suggest_composite_taxonomies

Filters which Search Bar taxonomies also produce “term + product title” completion inputs.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Runs per product during document preparation. The default is every Search Bar taxonomy or attribute field whose name contains “brand”. The result is only cast to an array, and names that are not Search Bar taxonomy fields have no effect. Takes effect on the next sync.

Arguments

  1. $taxonomies (string[]): Taxonomy names that get composite inputs.
  2. $post (\WP_Post): Product post.
  3. $product (\WC_Product|false): WooCommerce product, or false.

Returns string[]: Taxonomy names.

xfacets_search_suggest_input_limit

Filters the maximum number of completion inputs stored for one product.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesManaged search
Runs onProduct sync
IntroducedIntroduction version unknown

Runs per product during document preparation. The result is clamped to 1–50. Takes effect on the next sync.

Arguments

  1. $limit (int): Maximum inputs. Default 20.
  2. $post (\WP_Post): Product post.
  3. $product (\WC_Product|false): WooCommerce product, or false.

Returns int: Maximum inputs.

xfacets_validate_search_field

Filters the validation result of a search field whose source is not built in.

PropertyValue
KindFilter (return a value)
StabilityAdvanced
Search enginesNot tied to a search engine
Runs onwp-admin, Storefront pages, REST requests
IntroducedIntroduction version unknown

Reached only for sources the registry does not know, whenever a field is validated: on save in wp-admin and while fields are resolved for queries and suggestions. Only true or a WP_Error is accepted; any other return rejects the field.

Arguments

  1. $result (null): Always null.
  2. $source (string): Semantic source identifier.
  3. $source_value (string): Source value.
  4. $registry (\XFacets_Search_Field_Registry): Registry.

Returns true|\WP_Error|null: True to accept, a WP_Error to reject with a message.

Not for integrations

The names below exist in the plugin but are not integration points. Do not build on them: they can change or disappear without notice. An inactive entry is not deprecated in any released version; it is simply not reached by current code.

Internal hooks and events

  • xfacets_after_display_results: Fires after the first-paint product grid of a storefront listing has been produced.
  • xfacets_analyzer_profile: Filters the analyzer profile chosen by the legacy site-wide resolver.
  • xfacets_analyzer_profile_map: Filters the locale-to-analyzer-profile map.
  • xfacets_search_bar_trending_result_warnings: Filters the Trending verification warnings before the live check runs.
  • xfacets_site_serves_multiple_languages: Filters whether the site counts as multilingual for the legacy site-wide analyzer.
  • xfs_api_base: Filters the control-plane API origin used for updates, licensing and managed slot calls.
  • xkit-i18n: Filters the translated strings printed as window.xkit_i18n for the shared scripts.
  • xkit-params: Filters the parameters printed as window.xkit_params for the shared scripts.
  • xfacets-filter-drawer-open: Fired on document just before a filter drawer opens, so other drawers close.
  • xfacets_initial_load_data_from_server: Hydration handshake: the page bootstrap triggers it on window once the first-paint facet data has been printed, and every filter form app hydrates from that data.

Inactive entries

  • xfacets_facet_usage_events_circuit_breaker: Filters the backend circuit-breaker policy of one public REST route. Inactive: The facet usage events route only spends the request budget; it never records failures or timings, so this policy is never read.
  • xfacets_synonyms_set_name: Filters the Elasticsearch synonym set name of the legacy plugin-built mapping. Inactive: Only the legacy mapping file calls get_set_name(), and that file is required only by XFacets_Product_Indexable::generate_mapping(), which has no production caller.
  • xfacets-facets.mounted: Intended to fire after the facets app mounted, for result-area integrations. Dead: apps/Facets.vue triggers it on .xfacets-search-results-wrapper, which no rendered element carries, so no listener ever receives it.

WooCommerce data hooks on WPXFacets models

Hook families WooCommerce WC_Data emits for XFacets models. Compatibility notes, not XFacets-declared contracts; behavior is unchanged and existing callbacks keep working.

Name patternKindNote
woocommerce_after_xfacets_facet_object_saveAction( XFacets_Facet $facet, $data_store ) after every facet save.
woocommerce_after_xfacets_filter_form_object_saveAction( XFacets_Filter_Form $form, $data_store ) after every filter form save.
woocommerce_before_xfacets_facet_object_saveAction( XFacets_Facet $facet, $data_store ) before every facet save: admin editing, installation seeding and imports.
woocommerce_before_xfacets_filter_form_object_saveAction( XFacets_Filter_Form $form, $data_store ) before every filter form save: admin editing, installation seeding and imports.
woocommerce_pre_delete_xfacets_facetFilter( null $check, XFacets_Facet $facet, bool $force_delete ) before a facet is deleted; a non-null return skips that deletion. Deleting a filter form deletes its facets one by one and still deletes the form when a facet deletion is skipped.
woocommerce_pre_delete_xfacets_filter_formFilterNever emitted: delete() is overridden and does not call the inherited implementation.
woocommerce_xfacets_facet_get_{prop}Filter( mixed $value, XFacets_Facet $facet ) on every view-context getter read (the default context) of slug, title, type, display_type, source, source_value, form_id, show_when, show_see_more, limit_visible_terms, order, search_fields, enable_exclude and use_swatches. The facet data store saves post_title and post_name from view-context reads, so a callback’s value can be persisted. The plugin’s Polylang integration filters titles outside wp-admin.
woocommerce_xfacets_filter_form_get_{prop}Filter( mixed $value, XFacets_Filter_Form $form ) on get_name() reads in the default view context and on every get_settings() read, which has no context parameter. The form data store saves post_title from a view-context get_name(), so a callback’s value can be persisted.

Hooks WPXFacets calls but does not own

WPXFacets also runs these WordPress, WooCommerce and WPML hooks. They belong to those projects and are documented there, not by WPXFacets.

  • loop_shop_per_page
  • plugin_locale
  • woocommerce_after_main_content
  • woocommerce_after_shop_loop
  • woocommerce_archive_description
  • woocommerce_before_main_content
  • woocommerce_before_shop_loop
  • woocommerce_no_products_found
  • woocommerce_shop_loop
  • woocommerce_shop_loop_header
  • woocommerce_shortcode_after_products_loop
  • woocommerce_show_page_title
  • woocommerce_sidebar
  • woocommerce_taxonomy_objects_product_cat
  • wp_search_stopwords
  • wpml_active_languages
  • wpml_current_language
  • wpml_default_language
  • wpml_element_language_code
  • wpml_object_id
  • wpml_post_language_details
  • wpml_switch_language

About this reference

Generated from the hooks.json manifest packaged in the released WPXFacets 0.1.18 plugin (schema 1, SHA-256 0fbf625d0c216bf7656b9d03512f314335f2b52f93b217ea7609a8a5d54e1ae0). The contracts themselves are the documentation comments in the plugin source; this page is regenerated from each release’s manifest. Introduction versions come from each contract’s own record: four entries were introduced in 0.1.18, and an introduction version shown as unknown has not been established.