Skip to main content

Hooks

The @wordpress/hooks package is a lightweight and efficient EventManager for JavaScript, providing a hooks system similar to WordPress PHP hooks. It allows you to add actions and filters to extend and modify behavior in your applications.

Installation

You can install the package using npm:
npm install @wordpress/hooks --save
This package assumes your code will run in an ES2015+ environment. If you’re targeting environments with limited support for modern JavaScript features, include the polyfill from @wordpress/babel-preset-default.

Basic Usage

Creating a Custom Hooks Instance

You can create your own isolated hooks instance:
import { createHooks } from '@wordpress/hooks';

myObject.hooks = createHooks();
myObject.hooks.addAction( 'hookName', 'namespace', callback );

Using the Global Instance

The package provides a default global instance accessible through named exports:
import { addAction, doAction } from '@wordpress/hooks';

addAction( 'hookName', 'namespace', callback );
doAction( 'hookName' );
In WordPress, hooks are accessible via wp.hooks.addAction(), wp.hooks.addFilter(), etc.

Key Differences from PHP Hooks

One notable difference from the PHP hooks API is that JavaScript hooks require a namespace as the second argument. The namespace uniquely identifies a callback in the form vendor/plugin/function.
// JavaScript requires namespace
addAction( 'hookName', 'my-plugin/my-function', callback, priority );

// PHP doesn't require namespace
add_action( 'hook_name', 'callback', priority );

Actions API

addAction( hookName, namespace, callback, priority )

Adds an action callback to be executed when the action is triggered.
hookName
string
required
The name of the action hook. Must be a non-empty string containing only numbers, letters, dashes, periods, and underscores. Cannot begin with __.
namespace
string
required
A unique namespace for the callback in the form vendor/plugin/function. Must be a non-empty string containing only numbers, letters, dashes, periods, underscores, and slashes.
callback
function
required
The function to be executed when the action is triggered.
priority
number
default:"10"
The priority at which the callback should be executed. Lower numbers execute earlier.
import { addAction } from '@wordpress/hooks';

addAction( 'myPlugin.init', 'my-plugin/init-handler', () => {
	console.log( 'Plugin initialized!' );
}, 10 );

doAction( hookName, …args )

Executes all callbacks registered for the given action hook synchronously.
hookName
string
required
The name of the action hook to execute.
args
...any
Arguments to pass to the callback functions.
import { doAction } from '@wordpress/hooks';

doAction( 'myPlugin.init', arg1, arg2 );

doActionAsync( hookName, …args )

Executes all callbacks registered for the given action hook asynchronously.
hookName
string
required
The name of the action hook to execute.
args
...any
Arguments to pass to the callback functions.
return
Promise
A Promise that resolves when all callbacks have been executed.

removeAction( hookName, namespace )

Removes the callback registered for the given action hook and namespace.
hookName
string
required
The name of the action hook.
namespace
string
required
The namespace of the callback to remove.
import { removeAction } from '@wordpress/hooks';

removeAction( 'myPlugin.init', 'my-plugin/init-handler' );

removeAllActions( hookName )

Removes all callbacks registered for the given action hook.
hookName
string
required
The name of the action hook.

hasAction( hookName, namespace )

Checks if any callbacks are registered for the given action hook.
hookName
string
required
The name of the action hook.
namespace
string
Optional namespace to check for a specific callback.
return
boolean | number
If namespace is provided, returns the priority of that callback or false if not found. Otherwise, returns the number of callbacks registered.

didAction( hookName )

Returns the number of times an action has been executed.
hookName
string
required
The name of the action hook.
return
number
The number of times the action has been executed.

doingAction( hookName )

Checks if an action is currently being executed.
hookName
string
Optional name of the action hook. If omitted, checks if any action is currently executing.
return
boolean
Whether the action is currently being executed.

Filters API

addFilter( hookName, namespace, callback, priority )

Adds a filter callback to modify a value when the filter is applied.
hookName
string
required
The name of the filter hook.
namespace
string
required
A unique namespace for the callback in the form vendor/plugin/function.
callback
function
required
The function to be executed. Must return a value.
priority
number
default:"10"
The priority at which the callback should be executed.
import { addFilter } from '@wordpress/hooks';

addFilter( 'myPlugin.content', 'my-plugin/uppercase', ( content ) => {
	return content.toUpperCase();
}, 10 );

applyFilters( hookName, value, …args )

Applies all callbacks registered for the given filter hook synchronously.
hookName
string
required
The name of the filter hook to apply.
value
any
required
The value to filter.
args
...any
Additional arguments to pass to the callback functions.
return
any
The filtered value.
import { applyFilters } from '@wordpress/hooks';

const filtered = applyFilters( 'myPlugin.content', 'hello world' );
console.log( filtered ); // "HELLO WORLD"

applyFiltersAsync( hookName, value, …args )

Applies all callbacks registered for the given filter hook asynchronously.
hookName
string
required
The name of the filter hook to apply.
value
any
required
The value to filter.
args
...any
Additional arguments to pass to the callback functions.
return
Promise
A Promise that resolves to the filtered value.

removeFilter( hookName, namespace )

Removes the callback registered for the given filter hook and namespace.
hookName
string
required
The name of the filter hook.
namespace
string
required
The namespace of the callback to remove.

removeAllFilters( hookName )

Removes all callbacks registered for the given filter hook.
hookName
string
required
The name of the filter hook.

hasFilter( hookName, namespace )

Checks if any callbacks are registered for the given filter hook.
hookName
string
required
The name of the filter hook.
namespace
string
Optional namespace to check for a specific callback.
return
boolean | number
If namespace is provided, returns the priority of that callback or false if not found. Otherwise, returns the number of callbacks registered.

didFilter( hookName )

Returns the number of times a filter has been applied.
hookName
string
required
The name of the filter hook.
return
number
The number of times the filter has been applied.

doingFilter( hookName )

Checks if a filter is currently being applied.
hookName
string
Optional name of the filter hook. If omitted, checks if any filter is currently being applied.
return
boolean
Whether the filter is currently being applied.

Advanced Features

createHooks()

Creates a new isolated hooks instance.
return
object
A new Hooks instance with all the hooks methods.
import { createHooks } from '@wordpress/hooks';

const customHooks = createHooks();
customHooks.addAction( 'init', 'my-namespace/init', () => {
	console.log( 'Custom hooks initialized' );
} );

Hook Events

Whenever an action or filter is added or removed, a matching event is triggered:
  • hookAdded: Triggered when addFilter() or addAction() is called, passing values for hookName, functionName, callback, and priority.
  • hookRemoved: Triggered when removeFilter() or removeAction() is called, passing values for hookName and functionName.
import { addAction } from '@wordpress/hooks';

// Listen for hooks being added
addAction( 'hookAdded', 'my-plugin/hook-listener', ( hookName, namespace ) => {
	console.log( `Hook added: ${hookName} (${namespace})` );
} );

The “all” Hook

In non-minified builds, you can register a filter or action that will be called on all hooks:
import { addAction } from '@wordpress/hooks';

addAction( 'all', 'my-plugin/debug', ( hookName ) => {
	console.log( `Hook executed: ${hookName}` );
} );
The all hook is useful for debugging but is stripped from production code for performance reasons.

Complete Example

import { addAction, doAction } from '@wordpress/hooks';

// Register an action
addAction( 'app.loaded', 'my-plugin/on-load', () => {
	console.log( 'App loaded!' );
}, 10 );

// Register another action with higher priority
addAction( 'app.loaded', 'my-plugin/on-load-early', () => {
	console.log( 'This runs first!' );
}, 5 );

// Trigger the action
doAction( 'app.loaded' );
// Output:
// "This runs first!"
// "App loaded!"

Version

Current version: 4.40.0

Build docs developers (and LLMs) love