Complete Guide to WordPress Hooks in Order: From muplugins_loaded to shutdown

Complete Guide to WordPress Hooks in Order

Mastering WordPress hooks is key to crafting flawless plugins and themes—unlock error-free development with this exciting guide I’m creating just for you!

Below is a serialized list of key WordPress hooks in the order they typically fire during a standard page request, starting from the early initialization phase through to the end of the process. This includes the hooks we’ve discussed (plugins_loaded, after_setup_theme, init, wp_loaded, etc.) and others that fill out the sequence. Note that the exact order can vary slightly depending on specific conditions (e.g., multisite, custom plugins), but this represents the general flow for a typical front-end request.

Serialized WordPress Hooks Order

  1. muplugins_loaded
    • Fires after Must-Use plugins are loaded (early, before regular plugins).
  2. plugins_loaded
    • Fires after all active plugins are loaded and their main files executed.
  3. after_setup_theme
    • Fires after the active theme’s functions.php is loaded, for theme setup.
  4. init
    • Fires after WordPress core is initialized (e.g., globals set, rewrite rules ready).
  5. wp_loaded
    • Fires after WordPress is fully loaded, before the main query runs.
  6. parse_request
    • Fires during URL parsing, before query vars are finalized.
  7. send_headers
    • Fires when HTTP headers are about to be sent (can be used to modify headers).
  8. pre_get_posts
    • Fires just before the main WP_Query is executed, for query modification.
  9. posts_selection
    • Fires after the main query retrieves posts, but before further processing.
  10. wp
    • Fires after the main query is fully populated ($wp_query is set).
  11. template_redirect
    • Fires just before WordPress selects and loads the template file.
  12. get_header
    • Fires when the header template is about to be loaded (e.g., header.php).
  13. wp_head
    • Fires within the <head> section when wp_head() is called in the theme.
  14. loop_start
    • Fires at the beginning of The Loop in the template.
  15. the_post
    • Fires for each post in The Loop, setting up post data.
  16. loop_end
    • Fires after The Loop finishes processing posts.
  17. get_footer
    • Fires when the footer template is about to be loaded (e.g., footer.php).
  18. wp_footer
    • Fires just before the closing </body> tag when wp_footer() is called.
  19. shutdown
    • Fires at the very end of the PHP process, after all output is sent.

Notes

  • Conditional Hooks: Some hooks (e.g., ‘get_header’, ‘loop_start’) depend on the theme’s template structure and may not fire if the theme doesn’t call the corresponding functions (e.g., get_header()).
  • AJAX/Admin Variations: This sequence is for a front-end page load. Admin pages and AJAX requests have different flows (e.g., ‘admin_init’ instead of ‘init’ for admin).
  • Dynamic Hooks: Additional hooks like ‘wp_enqueue_scripts‘ (runs during ‘wp_head’) or custom hooks added by plugins/themes can intersperse this list.

Practical Example (Serialized in Code)

Here’s how you could test this sequence:

class HookChecker {
    public function __construct() {
        add_action( 'muplugins_loaded', array( $this, 'log_muplugins_loaded' ) );
        add_action( 'plugins_loaded', array( $this, 'log_plugins_loaded' ) );
        add_action( 'after_setup_theme', array( $this, 'log_after_setup_theme' ) );
        add_action( 'init', array( $this, 'log_init' ) );
        add_action( 'wp_loaded', array( $this, 'log_wp_loaded' ) );
        add_action( 'parse_request', array( $this, 'log_parse_request' ) );
        add_action( 'pre_get_posts', array( $this, 'log_pre_get_posts' ) );
        add_action( 'wp', array( $this, 'log_wp' ) );
        add_action( 'template_redirect', array( $this, 'log_template_redirect' ) );
        add_action( 'wp_head', array( $this, 'log_wp_head' ) );
        add_action( 'wp_footer', array( $this, 'log_wp_footer' ) );
        add_action( 'shutdown', array( $this, 'log_shutdown' ) );
    }

    public function log_muplugins_loaded() { error_log( '1. muplugins_loaded' ); }
    public function log_plugins_loaded() { error_log( '2. plugins_loaded' ); }
    public function log_after_setup_theme() { error_log( '3. after_setup_theme' ); }
    public function log_init() { error_log( '4. init' ); }
    public function log_wp_loaded() { error_log( '5. wp_loaded' ); }
    public function log_parse_request() { error_log( '6. parse_request' ); }
    public function log_pre_get_posts() { error_log( '7. pre_get_posts' ); }
    public function log_wp() { error_log( '8. wp' ); }
    public function log_template_redirect() { error_log( '9. template_redirect' ); }
    public function log_wp_head() { error_log( '10. wp_head' ); }
    public function log_wp_footer() { error_log( '11. wp_footer' ); }
    public function log_shutdown() { error_log( '12. shutdown' ); }
}

new HookChecker();

Log Output

1. muplugins_loaded
2. plugins_loaded
3. after_setup_theme
4. init
5. wp_loaded
6. parse_request
7. pre_get_posts
8. wp
9. template_redirect
10. wp_head
11. wp_footer
12. shutdown

Conclusion

This serialized list covers the main WordPress Hooks from start to finish for a typical front-end request. After wp_loaded, you’ve got hooks like wp, template_redirect, wp_head, wp_footer, and finally shutdown—each serving a specific purpose as WordPress builds and delivers the page. Let me know if you’d like me to expand on any of these!

Post a Comment