flush_rewrite_rules( bool $hard = true )

Removes rewrite rules and then recreate rewrite rules.

Parameters

$hardbooloptional
Whether to update .htaccess (hard flush) or just update rewrite_rules option (soft flush). Default is true (hard).

Default:true

More Information

This function is useful when used with custom post types as it allows for automatic flushing of the WordPress rewrite rules (usually needs to be done manually for new custom post types). However, this is an expensive operation so it should only be used when necessary.

Source

function flush_rewrite_rules( $hard = true ) {
	global $wp_rewrite;

	if ( is_callable( array( $wp_rewrite, 'flush_rules' ) ) ) {
		$wp_rewrite->flush_rules( $hard );
	}
}

Changelog

VersionDescription
3.0.0Introduced.

User Contributed Notes

  1. Skip to note 8 content
    register_activation_hook( __FILE__, 'plugin_activation' );
    function plugin_activation() {
    	update_option('plugin_permalinks_flushed', 0);
    }
    
    add_action( 'init', 'custom_query_vars' );
    function custom_query_vars() {
    	global $wp;
    
    	$wp->add_query_var( 'newfeed' );
    	add_rewrite_rule( '^newfeed/([^/]*)/?', 'index.php?newfeed=$matches[1]', 'top' );
    
    	if( !get_option('plugin_permalinks_flushed') ) {
    
    		flush_rewrite_rules(false);
    		update_option('plugin_permalinks_flushed', 1);
    
    	}
    }
  2. Skip to note 9 content

    If you want to flush rules while updating posts based on post type:

    function wpdoc_flush_rules_on_save_posts( $post_id ) {
    
        // Check the correct post type.
        // Example to check, if the post type isn't 'post' then don't flush, just return.
        if ( ! empty( $_POST['post_type'] && $_POST['post_type'] != 'post' ) {
            return;
        }
    
        flush_rewrite_rules();
    
    }
    
    add_action( 'save_post', 'wpdoc_flush_rules_on_save_posts', 20, 2);
  3. Skip to note 11 content

    A relatively simple way to flush rewrite rules on activation and deactivation hooks is not using flush_rewrite_rules() at all. Instead just clear the rewrite_rules option to force WordPress to recreate them at the right time.

    Example:

    register_activation_hook( __FILE__, 'wpdocs_wpdev_activate' );
    
    function wpdocs_wpdev_activate() {
    	// force rewrite rules to be recreated at the right time
    	delete_option( 'rewrite_rules' );
    }

    This avoids having to do complicated stuff like registering your custom post types in the activation hook or throwing and catching dedicated db option or transients as suggested in other notes…

  4. Skip to note 12 content

    This is how you would flush rewrite rules when a plugin is activated or deactivated:

    register_deactivation_hook( __FILE__, 'flush_rewrite_rules' );
    register_activation_hook( __FILE__, 'wdocs_flush_rewrites' );
    
    
    /**
     * Flush rewrite rules on activation
     */
    function wpdocs_flush_rewrites() {
    	// call your CPT registration function here (it should also be hooked into 'init')
    	wpdocs_custom_post_types_registration();
    	flush_rewrite_rules();
    }
  5. Skip to note 13 content

    If you’re developing a theme, while building it you can use this snippet of code that will flush rewrite rules when the file containing it is changed, or every 48 hours:

    // do not use on live/production servers
    add_action( 'init','maybe_rewrite_rules' );
    
    /**
     * Flush rewrite rules if the current file has changed and at least every 48 hours.
     */
    function maybe_rewrite_rules() {
    	if ( ! is_admin() ) {
    		return;
    	}
    
    	$ver = filemtime( __FILE__ ); // Get the file time for this file as the version number
    	$defaults = array( 'version' => 0, 'time' => time() );
    	$r = wp_parse_args( get_option( __CLASS__ . '_flush', array() ), $defaults );
    
    	if ( $r['version'] != $ver || $r['time'] + 172800 < time() ) { // Flush if ver changes or if 48hrs has passed.
    		flush_rewrite_rules();
    		// trace( 'flushed' );
    		$args = array( 'version' => $ver, 'time' => time() );
    		if ( ! update_option( __CLASS__ . '_flush', $args ) )
    			add_option( __CLASS__ . '_flush', $args );
    	}
    
    }
  6. Skip to note 14 content
    // flush rules and serve new rules instantly without page refresh
    add_action('init', function() {
        flush_rewrite_rules();
    });
    // Or, hook into wp tag, flush rules and do an internal refresh
    add_action('wp', function() {
        if( "1" !== get_option("my_rules_have_been_flushed") ) {
            flush_rewrite_rules();
            update_option('my_rules_have_been_flushed', '1');
            // now, redirect the request.
            wp_redirect( $_SERVER['REQUEST_URI'] );
            exit;
        }
    });

You must log in before being able to contribute a note or feedback.