WordPress Development
WordPress Hooks and Filters: How Actions and Filters Work and When to Use Them
Hooks are how WordPress extensions work. Understanding actions and filters separates site builders from developers. Here is the complete practical guide.
Simple Automation Solutions
··⌛ 9 min read
WordPress hooks — actions and filters — are the foundation of every customisation that does not require editing core files. They are how plugins modify WordPress behaviour, how themes add functionality, and how developers build clean, update-safe customisations. Understanding them separates WordPress developers from WordPress site builders.
What hooks are and how they work
WordPress executes code in a specific sequence when loading a page. At dozens of points in this sequence, WordPress fires a ‘hook’ — a named event that allows your code to run at that specific moment. There are two types:
- Action hooks: allow you to execute code at a specific point. Example:
wp_footerfires just before the closing body tag. You can hook into it to add custom scripts. - Filter hooks: allow you to intercept and modify a value before WordPress uses it. Example:
the_contentfires before WordPress displays post content. You can filter it to add content before or after every post.
The two core functions are add_action() to attach to action hooks and add_filter() to attach to filter hooks. Both take a hook name, a callback function, and optional priority and accepted argument count parameters.
Action hooks in practice
wp_head and wp_footer
These two hooks are the most commonly used actions. wp_head fires inside the HTML head element — use it to add meta tags, custom CSS, or analytics scripts that must load in the head. wp_footer fires before the closing body tag — use it to add deferred scripts.
Adding code via add_action to your child theme functions.php is safer and more maintainable than editing header.php or footer.php directly. Your code persists through theme updates; direct theme file edits do not.
init
The init hook fires after WordPress is loaded but before headers are sent. This is the correct hook for registering custom post types, custom taxonomies, and custom rewrite rules.
save_post
Fires whenever a post is saved or updated. Use it to run custom validation, trigger external API calls when content changes, or clear specific caches after updates.
wp_enqueue_scripts
The correct hook for loading CSS and JavaScript files. Never add scripts directly to header.php — always enqueue them via wp_enqueue_scripts to ensure correct loading order and dependency management.
Filter hooks in practice
the_content
Filters the content of every post before display. Common uses: adding a disclaimer below every post, adding a CTA after every blog post content, modifying shortcode output.
the_title
Filters the post title before display. Use with care — modifying titles can affect page titles and menu labels if not properly scoped.
excerpt_length and excerpt_more
Control the length and truncation string for automatically generated post excerpts. excerpt_length returns the number of words; excerpt_more returns the suffix appended when an excerpt is truncated.
wp_nav_menu_items
Filters the HTML output of navigation menus. Add dynamic items to menus without creating them in the admin — for example, adding a ‘Log In’ link that changes to ‘My Account’ for logged-in users.
Hook priority and order
When multiple functions are attached to the same hook, they execute in priority order. The default priority is 10 — lower numbers execute earlier, higher numbers execute later. Use priority deliberately:
- Priority 1-9: run before default WordPress and most plugin handlers
- Priority 10 (default): normal execution order
- Priority 11-99: run after most default handlers
- Priority 999: run last — useful when you need to override what other plugins have done
| Use case | Priority recommendation |
|---|---|
| Remove a hook added by another plugin | Same priority as the hook you are removing, or lower |
| Override a plugin’s filter output | Higher priority (e.g. 20) than the plugin’s hook |
| Add content after all plugins have processed | Priority 999 on the_content |
| Register CPTs before most other code runs | Priority 0 on init |
Removing hooks
Use remove_action() and remove_filter() to detach functions from hooks. This is how you prevent a plugin from doing something without modifying the plugin directly. Important: you must remove a hook at the same or later execution point than it was added, and you must know the exact function name, hook name, and priority used when it was added.
Practical examples
Use add_filter on the_content. Check if is_single() to apply only to single posts. Append your disclaimer HTML to the $content variable and return it.
Use add_action on template_redirect. Check if the user is logged in and if the current page is member-restricted. Use wp_redirect() to the login page if not authorised.
Use add_filter on woocommerce_checkout_fields to add, remove, or reorder checkout form fields. Return the modified fields array.
Use add_action on save_post. Parse the post content for the first image. Use set_post_thumbnail() to set it as the featured image if none is already set.
Need custom WordPress development with hooks and filters?
Simple Automation Solutions builds custom WordPress functionality using the correct hook-based architecture for businesses worldwide.
Frequently asked questions
Where should I add my action and filter hooks in WordPress?+
Add hooks in your child theme’s functions.php for site-specific customisations, or in a custom plugin for functionality that is independent of your theme. The rule of thumb: if the functionality should persist through a theme change, put it in a plugin. If it is tied to your current theme design, it can go in functions.php. Never add hooks to WordPress core files or parent theme files directly.
What is the difference between add_action and add_filter?+
add_action attaches a function to an action hook — your function executes at that point but does not need to return a value. add_filter attaches a function to a filter hook — your function receives a value, modifies it, and must return the modified value. Using add_filter without returning a value is a very common mistake that causes content to disappear or settings to be lost.
How do I find what hooks are available in WordPress?+
The official WordPress Developer Reference (developer.wordpress.org/reference/hooks/) lists all core hooks. For plugin-specific hooks, look in the plugin source code for do_action() and apply_filters() calls. The Query Monitor plugin’s Hooks & Actions panel shows every hook that fired during a page load in real time — invaluable for discovering the hook you need and verifying your code ran at the right time.
Simple Automation Solutions is a global digital product studio specialising in WordPress and Bubble.io. We serve founders, startups, and businesses worldwide — delivering production-ready websites built to rank, convert, and scale.
