WordPress Tip: Do Not Use Init For Rewrite Rule Flushing
Today I have a quick tip I want to share with everyone about rewrite rules in WordPress.
WordPress is awesome. It has a nice, fairly easy to use rewrite system. You can use it to add your own rewrite rules and do all sorts of awesome things using a plugin. A lot of new developers also forget they are integral to Custom Post Types & Taxonomies too. I’ve been asked on more than one occasion why a CPT is giving a 404 and they have simply forgotten to refresh their rewrite rules. Visiting the Permalinks options page is the most common way to do it, but what if you need to do it in a plugin/theme?
Too many times have I seen a plugin or a theme where someone has hooked their rewrite rules onto the init
hook, but then they go and spoil it all by having flush_rewrite_rules()
in there too. Please do not flush your rewrite rules on the init
hook. It is an expensive function and degrades performance quickly. That’s why WordPress keeps a cache of the rewrite rule array in the database, so it doesn’t have to keep recreating it.
The Better Way
A better was is to leave your rewrite rule additions on the init
hook, but run flush_rewrite_rules()
when your theme or plugin is activated. The correct hook for that in a theme is after_switch_theme
, and in the case of plugins you use the register_activation_hook()
function. There is something important to remember about rewrite rule flushing on plugin & theme activation.
When a user activates your theme or plugin WordPress will run the init
hook before your plugin/theme has been activated. This means because your rewrite rules are added on the init
hook they will not have been added to WordPress because your plugin was not active when the init
hook was fired.
The way around this is to simply have the function (or method if you are working in a class) you have attached to the init
hook run inside your activation hook just before flush_rewrite_rules()
.
This is one issue I always check first when registering Custom Post Types, Taxonomies, or my own custom rewrite rules within a plugin or theme. It can save a lot of head scratching wondering why your rewrite rules aren’t working correctly.