Back to Blog
Lesson 7 of the WordPress Plugin Development: Foundations (PHP & MVC) course
WordPressJune 25, 20263 min read

Mastering Hook Priorities in WordPress: A Practical Guide

Learn to control the execution order of your WordPress hooks. Master priority levels to resolve conflicts and ensure your plugin functions exactly as intended.

WordPressPHPHooksDevelopmentArchitectureplugin-development

Previously in this course, we covered Understanding WordPress Hooks to grasp the fundamental difference between actions and filters. Now that you can hook into the WordPress lifecycle, this lesson adds the ability to control when your code runs relative to other plugins and core functionality.

The Concept of Hook Priority

In WordPress, a single hook (like init or wp_enqueue_scripts) can have dozens of functions attached to it by different plugins, themes, and WordPress core. By default, every hook you add runs at priority 10.

When multiple functions are attached to the same hook, WordPress executes them in ascending order based on their priority value. A lower number means "earlier," and a higher number means "later."

If you don't specify a priority, WordPress assumes 10. If you need your code to modify something before another plugin acts on it, you need a priority lower than 10 (e.g., 5). If you need to override a change made by another plugin, you likely need a priority higher than 10 (e.g., 20).

Setting Priority Levels in add_action

The add_action and add_filter functions accept four parameters:

  1. The hook name.
  2. The callback function.
  3. The priority (integer, default 10).
  4. The number of arguments passed to the callback (default 1).

To change the execution order, you simply pass the third argument.

Worked Example: Controlling Script Injection

Imagine our Knowledge Base plugin needs to enqueue a custom stylesheet, but it must load after the theme's main stylesheet to ensure we can easily override its styles.

PHP
#6A9955">// In your Knowledge Base class constructor or initialization method:

#6A9955">// Default priority(10) - might load before the theme
add_action('wp_enqueue_scripts', [$this, 'load_plugin_styles']);

#6A9955">// Higher priority(20) - ensures it runs later than default-priority functions
add_action('wp_enqueue_scripts', [$this, 'load_plugin_styles_late'], 20);

By setting the priority to 20, we guarantee that load_plugin_styles_late executes after any function attached at the default priority of 10.

Debugging Hook Execution Order

When things go wrong, you often need to see exactly who is firing when. While you can manually inspect the wp_filter global array, it is rarely efficient in production.

I highly recommend using WordPress Query Monitor: Trace Queries and Hooks in Real-Time to visualize the hook stack. It displays every hook fired during the page load, the priority of each callback, and the component (plugin or theme) that registered it.

If you are debugging without tools, you can use a temporary var_dump inside your callback to see if your code is firing at the expected point in the WordPress Load Order: A Step-by-Step Guide to the Boot Process.

Hands-on Exercise

  1. Open your main plugin class.
  2. Add two different functions that print a string to the footer using the wp_footer action.
  3. Assign the first function a priority of 5 and the second a priority of 15.
  4. Refresh your site frontend and view the source code. Observe the order of your strings.
  5. Swap the priorities and observe how the output order changes in the browser.

Common Pitfalls

  • The "Zero" Trap: While you can use 0 or even negative numbers, avoid them unless absolutely necessary. These are reserved for core processes that must run before anything else.
  • The "Missing Argument" Bug: A common mistake is providing a priority but forgetting that the fourth parameter (accepted arguments) is still needed if your callback requires more than one parameter.
    • Incorrect: add_action('save_post', 'my_func', 20); (This will break if my_func needs the $post object).
    • Correct: add_action('save_post', 'my_func', 20, 2);
  • Over-optimization: Don't use extreme priorities (like 9999) just to "make sure" your code runs last. It makes your code harder to maintain and creates "priority wars" with other plugin developers. Start with 11 or 20 first.

Recap

Managing hook priority is about precision. By understanding that WordPress executes hooks in ascending numerical order, you gain the ability to influence the sequence of the entire application. Use Query Monitor to visualize the stack, keep your priority numbers reasonable, and always remember to define your argument count when moving beyond the default 10.

Up next: We will begin building our plugin's user interface by Creating Admin Menus.

Similar Posts