Removing CPT slug from URL results in 404 error for archive page

It took some time to figure out the issue, but I got it done.

Passing “https://wordpress.stackexchange.com/” for rewrite slug is not recommended, since it causes more problem than it solves, as in this case, causing 404 error in other pages.

So removing it was the first step.

Next, I had to write the following code in my ‘functions.php’:

  1. To remove the slug from the published posts:

    /**
     * Remove the slug from published post permalinks. Only affect our CPT though.
     */
    function sh_remove_cpt_slug( $post_link, $post, $leavename ) {
    
        if ( in_array( $post->post_type, array( 'my_cpt1' ) )
            || in_array( $post->post_type, array( 'my_cpt2' )
            || 'publish' == $post->post_status )
            $post_link = str_replace( "https://wordpress.stackexchange.com/" . $post->post_type . "https://wordpress.stackexchange.com/", "https://wordpress.stackexchange.com/", $post_link );
            return $post_link;
    }
    add_filter( 'post_type_link', 'sh_remove_cpt_slug', 10, 3 );
    

This will still cause an error since it specifies that only ‘post’ and ‘page’ post types can have url without post-type slug.

Now to teach WP that out CPT will also have URL without slug, we need to get this in our functions.php:

function sh_parse_request( $query ) {

    // Only loop the main query
    if ( ! $query->is_main_query() ) {
        return;
    }

    // Only loop 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( 'my_cpt1','my_cpt2' ) );
    }
}
add_action( 'pre_get_posts', 'sh_parse_request' );

Leave a Comment