Handle the JetSmartFilters frontend AJAX lifecycle and reinitialize behavior after provider DOM replacement. Use when JavaScript must react when filtering starts, rendered content updates, loading ends, or JSF initializes; when integrating sliders, galleries, analytics, accessibility, or other widgets; or when code references JetSmartFilters.events, ajaxFilters/start-loading, ajaxFilters/updated, ajaxFilters/end-loading, provider/content-rendered, or jet-filter-content-rendered.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Lonsdale201/wp-agent-skills --skill jsf-frontend-events --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Jsf Frontend Events?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lonsdale201-jsf-frontend-events)More formats (shields.io, HTML) on the badges page.
---
name: jsf-frontend-events
description: >-
Handle the JetSmartFilters frontend AJAX lifecycle and reinitialize behavior
after provider DOM replacement. Use when JavaScript must react when filtering
starts, rendered content updates, loading ends, or JSF initializes; when
integrating sliders, galleries, analytics, accessibility, or other widgets;
or when code references JetSmartFilters.events, ajaxFilters/start-loading,
ajaxFilters/updated, ajaxFilters/end-loading, provider/content-rendered, or
jet-filter-content-rendered.
metadata:
wp-skills-author: "Soczó Kristóf"
wp-skills-contact: "mailto:lonsdale201@hotmail.com"
wp-skills-plugin: "jet-smart-filters"
wp-skills-plugin-version-tested: "3.8.3.1"
wp-skills-php-min: "7.4"
wp-skills-last-updated: "2026-07-21"
---
# JetSmartFilters frontend events
Subscribe to the JSF event bus and scope every callback. For a listing, the
three essential lifecycle channels are:
| Channel | Callback arguments | Meaning |
|---|---|---|
| `ajaxFilters/start-loading` | `provider, queryId` | A real AJAX request started; preloader is active |
| `ajaxFilters/updated` | `provider, queryId, response, requestOptions` | Response was processed and provider DOM/fragments were updated |
| `ajaxFilters/end-loading` | `provider, queryId` | Loading teardown ran and the preloader was hidden |
Use `updated` to read or initialize the new DOM. Use `end-loading` for a
global “cycle finished” UI state. They are not aliases.
## Load a companion script after JSF
JSF enqueues its public script in `wp_footer` only on pages where filters were
rendered. Queue the bridge after JSF has enqueued itself and before footer
scripts print:
```php
add_action( 'wp_footer', static function (): void {
if ( ! wp_script_is( 'jet-smart-filters', 'enqueued' ) ) {
return;
}
wp_enqueue_script(
'acme-jsf-bridge',
plugins_url( 'assets/js/jsf-bridge.js', __FILE__ ),
array( 'jet-smart-filters' ),
'1.0.0',
true
);
}, 16 );
```
## Subscribe with provider/query scoping
```js
(() => {
const targetProvider = 'jsf-listing';
const targetQueryId = 'catalog-listing';
const isTarget = (provider, queryId) =>
provider === targetProvider && queryId === targetQueryId;
const bind = () => {
const bus = window.JetSmartFilters?.events;
if (!bus?.subscribe) {
return;
}
bus.subscribe('ajaxFilters/start-loading', (provider, queryId) => {
if (!isTarget(provider, queryId)) return;
document.querySelector('.catalog-shell')?.setAttribute('aria-busy', 'true');
});
bus.subscribe(
'ajaxFilters/updated',
(provider, queryId, response, requestOptions) => {
if (!isTarget(provider, queryId)) return;
initCatalogWidgets(document.querySelector('#catalog-listing'));
}
);
bus.subscribe('ajaxFilters/end-loading', (provider, queryId) => {
if (!isTarget(provider, queryId)) return;
document.querySelector('.catalog-shell')?.setAttribute('aria-busy', 'false');
});
};
if (window.JetSmartFilters?.events) {
bind();
} else {
document.addEventListener('jet-smart-filters/before-init', bind, { once: true });
}
})();
```
Make `initCatalogWidgets()` idempotent: destroy or detect an existing widget
before recreating it.
## Other useful events
- DOM `jet-smart-filters/before-init`: JSF global exists; filter discovery has
not run.
- DOM `jet-smart-filters/inited`: initial filter groups are available.
- Bus `provider/content-rendered`: callback receives
`provider, $provider` after provider HTML and builder integrations render.
It has no query ID, so it is insufficient alone when several instances share
a provider.
- Legacy jQuery `jet-filter-content-rendered`: document event with
`event, $provider, filterGroup, provider, queryId`. Prefer the event bus in
new code; keep this only for a legacy integration contract.
- A provider element may receive `jet-filter-data-updated` for providers that
return data rather than HTML.
## Failure and concurrency rules
- A “start” event is not proof that content changed.
- In 3.8.3.1 a newer request aborts the previous XHR, and the abort path can
skip `end-loading`. Do not maintain an unbounded global counter that assumes
perfect start/end pairs.
- Key UI state by provider/query ID and make repeated cleanup harmless.
- `updated` fires on successful processing. Use application-level monitoring
if failed AJAX requests must also be reported.
- Prefer delegated click/input handlers for elements inside the replaced
wrapper.
## References
Verified against JetSmartFilters 3.8.3.1 source:
- `includes/filters/manager.php:22-112`
- `assets/js/public.js` channels `ajaxFilters/start-loading`,
`ajaxFilters/updated`, `ajaxFilters/end-loading`,
`provider/content-rendered`
- `assets/lib/jet-plugins/jet-plugins.js`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!