Custom Post Type

Flush Permalinks On Custom Post Type

WordPress has the ability to have different post types, the main post type you will use in WordPress is the post type called Post. But there are other defaults such as Pages and Attachments. All the post types in WordPress are stored in the same table wp_posts there is a column on this table which will decide the type of post, this is defined as post_type.

In version 3.0 of WordPress a function was created to allow you to easily create your own post types.

Since WordPress allowed you to create your own custom post types it meant that you could now use this WordPress as a CMS.

To register a new post type in WordPress you need to use the function register_post_type( $post_type, $args ).

add_action( 'init', 'create_post_type' );

function create_post_type() 
    $args = array();
    register_post_type( 'post_type_name', $args);

To learn more about custom post types you can view this tutorial Creating A Custom Post Type In WordPress

Changing The Slug

One of the arguments that you can pass into the register_post_type() is the rewrite argument, this allows you to change this post type to use it's own permalink structure and not the default WordPress setting.

If you have defined a permalink structure of /blog/post-name then any new custom post types that you define will inherit this permalink structure and will be prefixed with blog and the URL will look like this /blog/products/custom-post-type.

This obviously isn't going to work for a section for your products, you need to be able to remove the blog prefix so you are left with simply /products/custom-post-type.

To do this you need to extend the rewrite option when registering your new post type. Using the rewrite option you can define the URL that you want to use for your products section. There are two options that you need to define on the rewrite section, this is with_front and slug.

Using the with_front option and setting it to false you will remove any prefix that is defined from the permalink structure, if this is set to true then it will continue using the rules defined by the permalink page.

The slug is used to customise the permalink structure that you want to use on this custom post type.

Use the following option on the rewrite to remove the blog prefix and define the slug as products.

'rewrite' => array(
    'with_front' => false,
    'slug'       => 'products'

Flush Rewrite Rules

When you change the rewrite rules on register post types then you will need to rewrite the rules or WordPress will just display a 404 page as it won't be able to find the post type rules.

When you flush the rewrite rules it will refresh the permalink structure to make the URL rewriting work correctly again.

There are a few ways you can rewrite the permalink rules, you can either visit the permalink page, by going to Settings -> Permalink.

Or you can do this in code by using the function flush_rewrite_rules() applying this after you register the new post types means it will fix the permalink structure.

add_action( 'init', 'create_post_type' );

function create_post_type() 
    $args = array();
    register_post_type( 'post_type_name', $args);

The problem with the above code is that we are flushing the rewrite rules on the init action, which means it will run on every page load. Flushing the rewrite rules on every page load will have a big performance hit on your website loading speed, therefore we need to make sure that we do this at a different time.

As custom post type registration code should live in a plugin then we can make sure we only flush the rules on plugin activation.

add_action( 'init', 'create_post_type' );
function create_post_type() {
    register_post_type( 'post_type_name', $args);

function flush_rewrite_rules() {

register_activation_hook( __FILE__, 'flush_rewrite_rules' );
Back to top

Gain access to all tutorials

  • Premium tutorials covering WordPress, Laravel and VueJS
  • Download premium content
  • Download premium WordPress plugins
  • Only $5 a month

Join Paulund


  1. Mahesh Waghmare says:

    Nice article. Clear lot of things. But, Is `flush_rewrite_rules()` used in `init` hook?

    1. Paul says:

      Hi Mahesh, that was an example of what not to do. If you read the paragraph underneath it says about it being an expensive function to do on init and can slow down your page speeds. I included in this article as I often see it being used in init so I wanted to make sure people understand this can be a problem.