If you create a custom post type in WordPress, its slug will be added to the permalink (URL) structure by default.  So there are times that you want to stray from this regular permalink structure. This can be desirable for grouping types of posts together, but it can also result in longer, harder-to-remember URLs.  At first glance this doesn’t seem to be that difficult to accomplish, but then you start looking through the WordPress.org forums for a solution and come back with several different “solutions” and none of which work for you.

For these reasons we want to share the code that will definitely solve your problem. Just paste the following code in your functions.php file and replace “your_post_type” with the slug of the post type you wish to drop the slug from.

 <?php 
/* Remove the slug from published post permalinks. Only affect our custom post type, though.*/
 
function shapeofweb_remove_cpt_slug( $post_link, $post, $leavename ) { 
    if ( 'your_post_type' != $post->post_type || 'publish' != $post->post_status ) {
        return $post_link;
    }
 
    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
 
    return $post_link;
}
add_filter( 'post_type_link', 'shapeofweb_remove_cpt_slug', 10, 3 );

function shapeofweb_parse_request_trick( $query ) {
 
    // Only noop the main query
    if ( ! $query->is_main_query() )
        return;
 
    // Only noop our very specific rewrite rule match
    if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }
 
    // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'page', 'your_post_type' ) );
    }
}
add_action( 'pre_get_posts', 'shapeofweb_parse_request_trick' );

That’s it! Just change both instances of “your_post_type” to the slug of your custom post type.