Why doesn’t flush_rewrite_rules() work on my plugin?

One common issue that people run into when using custom post types in their plugin is that the pretty permalink structure doesn’t seem to take hold on plugin activation.

When adding new paths into the permalink structure, like with a new custom post type, you typically need to run flush_rewrite_rules() in order for them to take hold. One common piece of advice people give is to visit the Permalinks page in the Settings menu in wp-admin. The reason for this is that page runs flush_rewrite_rules() on load.

The problem with this advice is that you do not want to have to tell your plugin users that they have to visit that page after they activate your plugin. They should be able to click “activate” and it should just work.

One would think that if you add flush_rewrite_rules() to the activation function for your plugin that that should do the trick, right?

No.

Well, yes and no.

If you call register_activation_hook when you are supposed to, not in a hook, then it will run well before your custom post type is registered — in init.  So it never actually gets to init, and your rewrite rules are never flushed.

So you do need to call flush_rewrite_rules() in your activation function, but you need to register your custom post type there as well.

Something like this:

function my_plugin_activate() {
  register_my_custom_post_type();
  flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'my_plugin_activate' );

I’ve run into this myself and lost time trying to debug what’s going on. If you are ever trying to figure out why something isn’t happening when you think it should, look at the hooks.

Subsequently, if you don’t think you can do something in WordPress, you’re probably wrong. There are hooks for everything.

I hope that it will help someone else avoid this pitfall.

Image credit