Actions and filters are the two types of WordPress hooks — the mechanism that makes the entire plugin and theme ecosystem possible. Understanding the difference between them and when to use each one is fundamental to writing clean WordPress code.
Problem: How do Actions and Filters differ in WordPress, and when should you use one over the other?
Solution: Use add_action() to run code at a specific point during WordPress execution — actions don't return values. Use add_filter() when you need to modify and return a value that WordPress then uses elsewhere.
Actions let you run code at a specific point during WordPress execution. They don't return values — they just do something.
// Add a hook
add_action( 'wp_footer', 'my_footer_script', 20 ); // priority 20 (default is 10)
function my_footer_script() {
echo '<script>console.log("Footer loaded");</script>';
}
// Trigger a custom action
do_action( 'myplugin_after_save', $post_id, $data );
// Hook into it elsewhere
add_action( 'myplugin_after_save', function( $post_id, $data ) {
// handle the event
}, 10, 2 ); // 10 = priority, 2 = number of accepted arguments
Filters let you modify a value before it's used. They must return the (possibly modified) value.
// Modify the excerpt length
add_filter( 'excerpt_length', function( $length ) {
return 30;
} );
// Apply a custom filter
$title = apply_filters( 'myplugin_post_title', get_the_title() );
// Hook into it
add_filter( 'myplugin_post_title', function( $title ) {
return strtoupper( $title );
} );
To remove a hook that was added by a plugin or theme:
// Remove a named function hook
remove_action( 'wp_head', 'wp_generator' ); // removes WP version from <head>
// Remove an anonymous function is not possible directly —
// the plugin must store the callable or use a named function.
NOTE: The priority argument controls execution order — lower numbers run first. When two callbacks share the same priority, they run in the order they were added. If you need to unhook a callback, avoid anonymous functions — they can't be referenced by remove_action() or remove_filter().