An action says “something is happening now”. Your function runs, does its work, and returns nothing important.
<?php
add_action("wp_footer", function (): void {
echo '<p class="credit">Built with PHP</p>';
});
When WordPress prints the footer, it calls do_action("wp_footer"), and every callback registered for it runs.
add_action() signature
add_action(string $hook, callable $callback, int $priority = 10, int $accepted_args = 1)
An action with arguments
Some actions pass data. save_post passes the post ID, the post object and whether it is an update.
<?php
add_action("save_post", function (int $post_id, WP_Post $post, bool $update): void {
if (wp_is_post_revision($post_id) || defined("DOING_AUTOSAVE") && DOING_AUTOSAVE) {
return;
}
error_log("Post {$post_id} was " . ($update ? "updated" : "created"));
}, 10, 3);
The last argument 3 tells WordPress to pass three arguments.
Your own action
Fire an action in your code so others can hook in.
<?php
function process_order(int $orderId): void
{
// ... do the work ...
do_action("myshop_order_processed", $orderId, "paid");
}
add_action("myshop_order_processed", function (int $id, string $status): void {
echo "Order $id is $status";
}, 10, 2);
process_order(1042);
Order 1042 is paid
Run something once: did_action
<?php
do_action("myshop_started");
do_action("myshop_started");
echo did_action("myshop_started") . " times";
2 times
Commonly used actions
| Action | Use |
|---|---|
init | Register post types, taxonomies, shortcodes |
after_setup_theme | Theme support (add_theme_support), menus |
wp_enqueue_scripts | Front-end scripts and styles |
admin_enqueue_scripts | Admin scripts and styles |
admin_menu | Admin pages |
admin_init | Register settings |
rest_api_init | Register REST routes |
wp_head, wp_footer | Print into <head> or before </body> |
save_post, delete_post | React to content changes |
wp_login, user_register | React to users |
plugins_loaded | All plugins are loaded |
Do not do heavy work on every request
An action such as init runs on every page load, including the admin and AJAX calls. Check the context first, and keep the code fast.
<?php
add_action("init", function (): void {
if (is_admin()) {
return; // only on the front end
}
// ...
});
Always check who and what
Actions that change data (a form handler, an admin-post action) must verify a nonce and the user’s capability (see WordPress Security Basics).