Quick answer: WordPress hooks are named points in the WordPress code where themes and plugins can add their own code or change data. There are two kinds. Actions let code run at a specific moment, such as when a post is published or when the page header is printed. Filters let code change a piece of data before WordPress uses it, such as the length of an excerpt or the text of an email. Hooks are why you can customise WordPress without editing core files, and why updates do not wipe out your changes when the code lives in the right place.
Why site owners should understand hooks
You do not need to write PHP to run a WordPress site. But knowing what hooks are helps you:
- Understand what a developer means when they say “we can do that with a filter”
- Judge whether a change should be a small snippet or a full plugin
- See why editing theme or core files directly is a bad idea
- Ask better questions when a plugin conflict breaks something
Almost every plugin you have installed works by attaching to hooks. Your SEO plugin hooks into the page head to print meta tags. Your form plugin hooks into page content to show forms. WooCommerce uses hundreds of hooks so other plugins can change how products, carts and checkout behave.
Actions: “do something at this point”
An action is a signal that WordPress sends at a certain moment. Code can listen for that signal and run when it happens.
Common actions include:
init, which runs early when WordPress has loadedwp_head, which runs inside the<head>section of each pagewp_footer, which runs just before the closing body tagsave_post, which runs when a post is savedpublish_post, which runs when a post is publishedwp_enqueue_scripts, which is the right place to load CSS and JavaScript files
Here is a simple action that adds a line of text to the footer of every page:
add_action( 'wp_footer', 'iws_footer_note' );
function iws_footer_note() {
echo '<p class="footer-note">Open Monday to Friday, 9am to 5pm.</p>';
}
The first line tells WordPress: when you reach wp_footer, run the function called iws_footer_note. The function prints the text.
A more practical example is sending a notification to a team chat when a post is published, or adding a tracking script to the head of each page. Both are actions.
Filters: “change this value before you use it”
A filter passes a piece of data through your code and expects it back, possibly changed. WordPress then uses the changed version.
Common filters include:
the_content, which lets you change post content before it is displayedthe_title, for post titlesexcerpt_length, which controls how many words appear in automatic excerptswp_mail, which lets you change outgoing email detailsupload_mimes, which controls which file types can be uploadedbody_class, which adds CSS classes to the page body
Here is a filter that shortens automatic excerpts to 30 words:
add_filter( 'excerpt_length', 'iws_excerpt_length' );
function iws_excerpt_length( $length ) {
return 30;
}
WordPress passes in its default number, the function returns 30, and WordPress uses 30.
The key rule with filters is that the function must always return a value. If it returns nothing, the data disappears. That is a common cause of blank titles or empty content after someone adds a snippet carelessly.
Priority and order
Several plugins can attach to the same hook. WordPress runs them in order of priority, a number you can add as a third argument. Lower numbers run first, and the default is 10.
add_filter( 'the_content', 'iws_add_disclaimer', 20 );
Priority matters when two pieces of code change the same thing. If your change keeps getting overwritten, a developer may raise the priority so it runs later. If you see odd behaviour after installing a new plugin, two plugins fighting over the same hook is one possible reason.
Removing hooks
Hooks can also be removed with remove_action() and remove_filter(). This is how developers switch off something a theme or plugin adds without editing that plugin’s files. For example, a theme might add a credit line to the footer, and a child theme can remove it.
Removing hooks needs care. The removal must match the original function name and priority exactly, and it must run after the original was added.
Where custom hook code should live
This is the part site owners most need to know. Custom code should never be added to WordPress core files, and it should not be added to a parent theme’s files either. Updates replace those files, and your changes vanish.
Safer places:
- A child theme’s functions.php file. Suitable for code tied to the look of the site. If you change themes, the code goes with the old theme.
- A small custom plugin. Better for site functions that should survive a theme change, such as custom post types, tracking scripts or email changes. Our guide to custom WordPress plugin development explains when this is worth doing.
- A must-use plugin. A file in the
wp-content/mu-pluginsfolder that always loads and cannot be switched off from the dashboard. Useful for critical site-wide code. - A code snippets plugin. Lets you add and toggle small snippets from the dashboard. Handy for small changes, but keep a record of what is in there.
Whatever you choose, keep the code in version control if you can. Our article on website version control covers the basics.
How to add a snippet without breaking your site
A single typo in PHP can take a site offline with a fatal error. WordPress 5.2 added a recovery mode that emails the admin when this happens, which helps, but it is better to avoid the problem:
- Take a full backup first.
- Test the snippet on a staging copy of the site, not on the live site.
- Use a child theme or a custom plugin, never core or parent theme files.
- Add one change at a time and check the site after each.
- Write a short comment above the code saying what it does and why.
- Remove snippets that are no longer needed.
Be cautious with snippets copied from forums or old blog posts. They may be written for an older version of WordPress or a different theme, and some include unsafe practices.
Hooks in themes and WooCommerce
Good themes add their own hooks so you can insert content in specific places, such as after the header or before the footer, without editing templates. WooCommerce does the same throughout product pages, the cart and checkout. That is how many WooCommerce extensions add fields, messages or upsells.
Hooks work alongside other theme tools. Our guides to the WordPress template hierarchy and custom fields explain the other main ways developers shape a site.
Hooks and the block editor
The block editor introduced in WordPress 5.0 uses JavaScript, and it has its own system of JavaScript filters for changing blocks. PHP actions and filters still work for everything that happens on the server, including how content is saved and displayed. For most business site changes, PHP hooks are still where the work happens. If you need entirely new blocks, see our article on custom Gutenberg blocks.
FAQ
What is the difference between an action and a filter?
An action runs code at a point in time and does not need to return anything. A filter receives a value, may change it, and must return it.
Can hooks slow down my site?
Hooks themselves are very light. The code attached to them can be slow, for example if it runs a heavy database query on every page load.
How do I find which hooks are available?
The WordPress developer documentation lists core hooks. Themes and plugins often document their own. Developers also use debugging plugins that list the hooks firing on a page.
Is it safe to edit functions.php?
In a child theme, yes, with a backup and testing first. Editing a parent theme’s functions.php is risky because updates overwrite it.
Small hooks, big flexibility
Hooks are the reason WordPress can be shaped to fit almost any business without hacking core files. Knowing the difference between actions and filters, and where custom code should live, helps you keep customisations safe through updates. If you want a WordPress site that is built cleanly and converts well, see our Turn visitors into customers service.