Moving the send_headers action to later in the load

As of WordPress 6.1, the send_headers hook has been moved to slightly later in the WordPress loading routine (ticket). Historically, all the is_ functions (like is_singular) wouldn’t work when you were determining which headers to send. With this change, moving `send_headers` to after WordPress parses the query, those functions now work properly.

People can now have more control over things like:

  • Managing caching behavior
  • Preloading assets with HTTP rel=preload headers
  • Conditionally executing redirects, and managing other non-200 status scenarios

Currently, these types of scenarios are often filtered in late actions like template_redirect; which is semantically confusing, and inefficient.

There’s a good example of code that becomes easier with this. In fact, it has already been changed in this ticket: the X-Pingback

HTTP header only needs to be sent for posts, and can now be sent at the right time (commit).

Let’s see what it means in terms of load order:

Action sequence before this change

  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts — WP main query.

Action sequence after this change

  • wp_loaded
  • parse_request
  • parse_query
  • pre_get_posts — WP main query.
  • send_headers

This should not affect any of your existing code negatively unless you were using send_headers to do things that really should have been happening on wp_loaded or parse_request. So please check your code for that! If you were doing that, just changing to an earlier hook should fix your problem.

For new code, you can now happily use all the is_ functions.

Props to @jonoaldersonwp, @sergeybiryukov, @aristath, @milana_cap for reviewing this post.

#6-1, #dev-notes, #performance

Leave a Reply

Your email address will not be published. Required fields are marked *