How to Use WordPress Hooks and Filters: A Complete Guide
WordPress is designed to be highly customizable. One of the main reasons developers can extend WordPress without modifying its core files is its hook system.
Hooks allow developers to connect their own PHP code to specific points in WordPress. They are commonly used in plugins, child themes, custom functionality, and integrations.
The two main types of WordPress hooks are actions and filters. Actions allow you to run code at a particular point, while filters allow you to modify data before WordPress uses or displays it.
Understanding hooks and filters is essential for anyone who wants to develop custom WordPress functionality safely and efficiently.
What Are WordPress Hooks?
A WordPress hook is a mechanism that allows your custom code to interact with WordPress at predefined points.
Instead of changing WordPress core files, you attach your function to a hook.
The basic concept looks like this:
WordPress
↓
Hook
↓
Your Function
↓
Modified Behavior
For example, instead of editing the WordPress core to add something to the footer, you can use the wp_footer action.
function my_footer_message() {
echo '<p>Welcome to our website!</p>';
}
add_action('wp_footer', 'my_footer_message');
WordPress executes your function when the wp_footer hook runs.
Why Use Hooks?
Hooks are one of the safest ways to customize WordPress because they allow you to extend functionality without modifying core files.
They can help you:
- Add custom functionality
- Modify existing content
- Add scripts and styles
- Customize the WordPress Dashboard
- Modify queries
- Change generated output
- Integrate third-party services
- Create custom plugin features
- Extend themes
The main advantage is that WordPress can be updated without your custom code being overwritten, provided your code is stored in an appropriate custom plugin or child theme.
Two Types of WordPress Hooks
WordPress provides two major categories of hooks:
- Action Hooks
- Filter Hooks
Although both are called hooks, they serve different purposes.
What Is an Action Hook?
An action hook allows you to execute your own function at a specific point during WordPress execution.
For example:
function my_custom_message() {
echo '<p>Hello from my custom function.</p>';
}
add_action('wp_footer', 'my_custom_message');
Here:
my_custom_message()is your function.wp_footeris the action hook.add_action()connects your function to the hook.
When WordPress reaches wp_footer, your function runs.
Understanding add_action()
The basic syntax is:
add_action(
'hook_name',
'function_name',
$priority,
$accepted_args
);
For example:
add_action(
'wp_footer',
'my_custom_message',
10,
1
);
The parameters are:
Hook Name
wp_footer
This identifies the WordPress action.
Callback Function
my_custom_message
This is the function WordPress should execute.
Priority
10
This controls when your function runs relative to other functions attached to the same hook.
Accepted Arguments
This specifies how many arguments your callback function expects.
Understanding Hook Priority
Suppose two functions use the same action:
add_action('wp_footer', 'function_one', 10);
add_action('wp_footer', 'function_two', 20);
The function with priority 10 normally runs before the function with priority 20.
Lower numbers generally execute earlier.
For example:
add_action('wp_footer', 'my_function', 5);
will normally run before:
add_action('wp_footer', 'another_function', 20);
The default priority is usually 10.
Example: Add a Footer Message
Here’s a practical example:
function my_footer_notice() {
echo '<div class="footer-notice">Thank you for visiting!</div>';
}
add_action('wp_footer', 'my_footer_notice');
This adds the message when WordPress executes the footer action.
Example: Add Code to the Header
You can use the wp_head action to add content to the document head.
function my_custom_header_code() {
echo '<meta name="custom-site" content="example">';
}
add_action('wp_head', 'my_custom_header_code');
However, for stylesheets, JavaScript, and other assets, WordPress’s enqueue functions are generally preferable to printing <script> or <link> tags directly.
Example: Load a Custom Stylesheet
Use wp_enqueue_style() together with an appropriate action:
function my_custom_styles() {
wp_enqueue_style(
'my-custom-style',
get_stylesheet_directory_uri() . '/custom.css'
);
}
add_action('wp_enqueue_scripts', 'my_custom_styles');
This approach allows WordPress to manage dependencies and asset loading more effectively.
Example: Load JavaScript
Similarly, JavaScript can be loaded using:
function my_custom_scripts() {
wp_enqueue_script(
'my-custom-script',
get_stylesheet_directory_uri() . '/custom.js',
array(),
null,
true
);
}
add_action('wp_enqueue_scripts', 'my_custom_scripts');
This is generally preferable to manually inserting JavaScript into templates.
What Is a Filter Hook?
A filter hook allows you to modify data before WordPress returns, stores, or displays it.
Unlike an action, a filter normally receives a value, modifies it, and returns the modified value.
For example:
function add_text_to_title($title) {
return $title . ' | My Website';
}
add_filter('the_title', 'add_text_to_title');
If a post title is:
Web Hosting Guide
the filtered result could become:
Web Hosting Guide | My Website
Understanding add_filter()
The basic syntax is:
add_filter(
'hook_name',
'function_name',
$priority,
$accepted_args
);
For example:
add_filter(
'the_title',
'my_custom_title',
10,
1
);
The structure is very similar to add_action().
The key difference is that the callback should normally return the filtered value.
Action vs Filter
The easiest way to understand the difference is:
Action
Do something.
function my_action() {
// Perform an operation.
}
add_action('some_hook', 'my_action');
Filter
Change something.
function my_filter($value) {
return $value . ' modified';
}
add_filter('some_hook', 'my_filter');
A useful mental model is:
Action → Execute code
Filter → Receive data → Modify data → Return data
Example: Modify Post Content
You can use the the_content filter to modify post content.
function add_custom_message_to_content($content) {
if (is_single()) {
$content .= '<p>Thanks for reading this article.</p>';
}
return $content;
}
add_filter('the_content', 'add_custom_message_to_content');
The important part is:
return $content;
Without returning the value, you can accidentally prevent the original content from being passed along correctly.
Example: Add a Disclaimer to Posts
A more practical example is adding a disclaimer:
function add_post_disclaimer($content) {
if (is_single() && in_the_loop() && is_main_query()) {
$content .= '<p class="post-disclaimer">This article is provided for informational purposes.</p>';
}
return $content;
}
add_filter('the_content', 'add_post_disclaimer');
The conditional checks help prevent the disclaimer from being inserted into every possible use of the content.
Filters Can Accept Multiple Arguments
Some filters provide more than one argument.
For example:
function modify_example($value, $post_id) {
return $value . ' - Post ID: ' . $post_id;
}
add_filter('some_filter', 'modify_example', 10, 2);
The final 2 tells WordPress that the callback expects two arguments.
Your function must match the arguments actually provided by the hook.
Important WordPress Hooks
WordPress has hundreds of hooks. Some frequently used ones include:
| Hook | Type | Common Purpose |
|---|---|---|
init | Action | Register custom functionality |
wp_loaded | Action | Run code after WordPress is fully loaded |
wp_head | Action | Add content to the document head |
wp_footer | Action | Add content near the footer |
wp_enqueue_scripts | Action | Load frontend assets |
admin_init | Action | Initialize admin functionality |
admin_menu | Action | Add admin menu items |
save_post | Action | Perform actions when posts are saved |
the_title | Filter | Modify post titles |
the_content | Filter | Modify post content |
excerpt_length | Filter | Modify excerpt length |
body_class | Filter | Add or modify body classes |
post_class | Filter | Modify post classes |
The correct hook depends on exactly what you want your code to accomplish.
How to Find the Right Hook
Finding the appropriate hook is an important part of WordPress development.
A good workflow is:
- Define what you want to change.
- Determine whether you need an action or filter.
- Search WordPress documentation or the relevant plugin/theme documentation.
- Check the hook’s arguments.
- Check when the hook runs.
- Test the callback on a staging site.
Avoid choosing a hook simply because its name sounds appropriate. The timing and available arguments matter.
Creating Your Own Custom Hook
Plugins and themes can also create their own hooks.
For an action:
do_action('my_custom_action');
Another function can then connect to it:
function my_custom_function() {
echo 'Custom action executed.';
}
add_action('my_custom_action', 'my_custom_function');
This makes your custom plugin or theme extensible.
Creating a Custom Filter
You can also create your own filter.
$message = apply_filters(
'my_custom_message',
'Default message'
);
Another function can modify it:
function change_custom_message($message) {
return $message . ' Have a great day!';
}
add_filter(
'my_custom_message',
'change_custom_message'
);
The result becomes:
Default message Have a great day!
This is useful when you’re developing reusable plugins or themes and want other developers to customize their behavior.
Removing an Action
Sometimes a plugin or theme adds an action that you don’t want.
You can remove it with:
remove_action(
'wp_footer',
'some_function'
);
However, the function must have been registered with compatible callback details, including the priority when it differs from the default.
For example:
remove_action(
'wp_footer',
'some_function',
20
);
The priority must match the priority used when the action was added.
Removing a Filter
Filters can similarly be removed:
remove_filter(
'the_content',
'some_filter_function'
);
Again, the callback and priority need to match the original registration.
Conditional Hooks
Sometimes you don’t want a function to run everywhere.
You can use WordPress conditional functions.
For example:
function my_custom_footer_message() {
if (is_page()) {
echo '<p>This is a page.</p>';
}
}
add_action('wp_footer', 'my_custom_footer_message');
Other useful conditional functions include:
is_single()
is_page()
is_home()
is_front_page()
is_category()
is_tag()
is_user_logged_in()
is_admin()
Using conditions helps prevent unnecessary processing and unwanted output.
Using Hooks in a Custom Plugin
For site functionality, custom hooks are often best placed in a plugin.
A basic plugin might look like:
my-custom-plugin/
└── my-custom-plugin.php
The file could contain:
<?php
if (!defined('ABSPATH')) {
exit;
}
/*
Plugin Name: My Custom Plugin
Description: Custom WordPress functionality.
Version: 1.0.0
*/
function my_custom_footer_message() {
echo '<p>Welcome to our website!</p>';
}
add_action('wp_footer', 'my_custom_footer_message');
This keeps your functionality separate from the active theme.
Hooks and Child Themes
If your customization is directly related to a theme, you can use hooks in a child theme.
For example, in the child theme’s functions.php:
function my_child_footer_message() {
echo '<p>Custom footer message.</p>';
}
add_action('wp_footer', 'my_child_footer_message');
This allows you to extend the parent theme without directly editing its files.
Common Mistakes With Hooks and Filters
1. Forgetting to Return Filtered Data
Incorrect:
function modify_title($title) {
$title .= ' | Website';
}
add_filter('the_title', 'modify_title');
Correct:
function modify_title($title) {
$title .= ' | Website';
return $title;
}
add_filter('the_title', 'modify_title');
2. Using the Wrong Hook
A function may be perfectly written but attached to the wrong hook.
Always check when the hook runs and what information it provides.
3. Incorrect Number of Arguments
If a hook provides two arguments:
add_filter('some_hook', 'my_function', 10, 2);
your callback should be prepared to receive them:
function my_function($value, $id) {
// Code.
}
4. Function Name Conflicts
Avoid generic names.
Instead of:
function custom_function() {
}
use a unique prefix:
function ehostpiya_custom_function() {
}
5. Running Expensive Code Too Often
Some hooks execute frequently.
Putting database-heavy or computationally expensive operations on frequently executed hooks can slow down a website.
Keep callbacks efficient and run them only when necessary.
6. Modifying WordPress Core
Hooks exist specifically so developers don’t have to modify WordPress core files.
Keep your custom code in an appropriate plugin or child theme.
Best Practices for WordPress Hooks and Filters
Follow these practices when working with hooks:
- Use actions for operations and filters for modifying values.
- Return the original value from filters when no modification is needed.
- Use unique function prefixes.
- Choose hooks based on their actual execution point.
- Use appropriate priorities.
- Specify the correct number of accepted arguments.
- Use conditional checks when functionality doesn’t need to run everywhere.
- Avoid expensive operations on frequently executed hooks.
- Don’t modify WordPress core files.
- Keep reusable functionality in a plugin.
- Use a child theme for theme-specific customizations.
- Test hooks after WordPress, plugin, and theme updates.
Actions vs Filters: Quick Reference
| Characteristic | Action | Filter |
|---|---|---|
| Main purpose | Execute code | Modify data |
| Function receives data | Sometimes | Usually |
| Must return a value | No | Yes |
| Common function | add_action() | add_filter() |
| Example | Add footer content | Modify post title |
| Can be removed | Yes | Yes |
Final Thoughts
WordPress hooks and filters provide a powerful way to customize and extend WordPress without modifying its core files. Actions allow your code to run at specific points, while filters let you modify data before WordPress uses or displays it.
Once you understand how add_action() and add_filter() work, you can build custom plugins, modify theme behavior, integrate external services, customize content, and create much more flexible WordPress websites.
The key is to choose the correct hook, understand the arguments it provides, use unique function names, return filtered values correctly, and keep custom functionality separated from WordPress core. With these practices, hooks and filters become one of the most useful tools for WordPress development.