Flush your rewrite rules on plugin/theme activation

I’ve actually been asked this a few times, and have seen others do it a few different ways. Anyway, here is my method:

/* Flush rewrite rules for custom post types. */
add_action( 'load-themes.php', 'frosty_flush_rewrite_rules' );

/* Flush your rewrite rules */
function frosty_flush_rewrite_rules() {
	global $pagenow, $wp_rewrite;

	if ( 'themes.php' == $pagenow && isset( $_GET['activated'] ) )

Obviously, if you’re using this in a plugin you’d change themes.php to plugins.php and load-themes.php to load-plugins.php. See comments below.



πŸ’πŸ½β€β™‚οΈ Husband to Jeana.
⚾️ Dodgers & Brewers.
πŸ’» PHP Engineer.
πŸŒπŸΌβ€β™‚οΈGolfer; ~14 HDC.
🌱 Hydroponic Gardner.
🍿 Plex nerd.
πŸš™ '15 WRX, '22 Model 3 LR, & '66 Corvette C2.

Follow me on Twitter @TheFrosty & Instagram @TheFrosty.

Articles: 292


  1. I wouldn’t recommend using it as-is for the plugins as it will flush the rewrite rules when any plugin is activated. You can use something like:

    if ( 'plugin.php' == $pagenow && isset( $_GET['activated'] ) && isset( $_GET['plugin'] && plugin_basename( __FILE__ ) == $_GET['plugin'] )

    or use the activation hook to flush the rewrite rules

    • Hello Pete Mall,

      I know you posted your comment long time ago. But, I have been working on WordPress since recently and have encountered a similar problem. I have rewrite rules in 2 different plugins and flush_rules() upon activation/deactivation of both these plugins. When I activate one plugin, it flushes all the rules of other plugin. How do I handle this?

      Appreciate your reply.

  2. Actually, plugins.php uses activate=true instead of activated and plugin will not be set. I would recommend using the activation hook for plugins to flush the rewrite rules (assuming the plugin is not being thrown in mu-plugins).

  3. A plugin may be installed/upgraded using svn/ftp/WordPress installer and there is no hook that will fire when a plugin is upgraded outside WordPress.

    I would save a version number in the options table and update it with every new version of the plugin. Use this version number to run all installation and update procedures for the plugin. If the option does not exist then it’s a new installation.

  4. Well one, why not a plugin activation hook? But anyway, I agree with Pete… I don’t really like activation hooks. They work okay for plugins, but they don’t scale particularly well (especially across networks). Themes don’t have them, and I’m not sure they ever will. They also don’t work for upgrades.

    Thus it’s better to have an upgrade routine you can also leverage for activation. Use a version number in the options table and trigger the routine on admin_init (not on the frontend), as Pete says. A number of my plugins leverage this, for example — check out this one.

    You’ll note I do use an activation hook there, but it’s only to set up an uninstall hook. On one hand, that’s also something that could be done on admin_init. On the other hand, I also am not a fan of uninstall hooks. (This is a particularly good use case for them, however.)

  5. Austin, this post just saved me a metric f-ton of time that would have otherwise been spent fumbling through the Codex…thanks man!

  6. is this still the best way? ive created a rewrite and want to do this without the user having the resave permalinks

      • I actually went with the after_switch_theme hook

        function reflush_rules() {
        global $wp_rewrite;
        add_action( ‘after_switch_theme’, ‘reflush_rules’ );

  7. Hello,

    I am using flush_rewrite_rules() in activation and deactivation of 2 different plugins and this is where I have a problem. When I activate plugin-1, the rewrite works fine. When I activate plugin-2, the rewrite of plugin-1 disappears. How do I fix this. Thanks a ton in advance.

Comments are closed.