Remove post type slugs from permalinks

⏲️ Time: 2 mins

One question that comes up semi-regularly with my support work for Custom Post Type UI is how to remove the post type slug from a given permalink. While I know that the slug is an important component, I also understand why some people may want to have it removed as well.

Without the slug in place, WordPress will be looking for just posts with the post post type, and thus not find a result to display.

For my tutorial today, I am going to provide some code that will help remove the slug from the generated permalink value as well as help WordPress still query for the post type when it’s making its request.

All of the code can go in your active theme’s functions.php or child theme if you have one of that. Alternatively you could create your own quick plugin or drop the code into a file put in your mu-plugin folder.

Permalink string

For the first part of the code, we will remove the slug from the generated permalink string. We are also only going to do this for published posts in our post type. Our example post type slug is movie and you will need to change that to whatever post type slug you’re removing in your own example.

function cptui_demo_remove_slug_from_permalink_string( $post_link, $post ) {

	if ( 'publish' !== $post->post_status ) {
		return $post_link;
	}

	if ( 'movie' === $post->post_type ) {
		$post_link = str_replace(
			'/' . $post->post_type . '/',
			'/',
			$post_link
		);
	}

	return $post_link;
}
add_filter( 'post_type_link', 'cptui_demo_remove_slug_from_permalink_string', 10, 2 );

Query modification

Now that we have the generated link recognized, the next thing to do is make sure WordPress includes the post type in its queries going forward. For that we will make use of the pre_get_posts action hook. This is a very actively used hook so we have multiple guards in place. We do not want this being run if you are in the WordPress admin dashboard and if not on the main query for a given request. Lastly, we need to make sure are querying by post name. If all conditions check out, then we add in our post type for consideration. By default, WordPress is only doing this for the post and page post types.

function cptui_demo_add_post_type_to_query( $query ) {

	if ( is_admin() || ! $query->is_main_query() ) {
		return;
	}

	if ( empty( $query->query['name'] ) ) {
		return;
	}

	$query->set(
		'post_type',
		[
			'post',
			'page',
			'movie',
		]
	);
}
add_action( 'pre_get_posts', 'cptui_demo_add_post_type_to_query' );

Once both parts are in place, you may need to visit your permalinks page to flush the rewrite rules, but once done, you should not be receiving any 404 errors for your slug-less post type posts any more.

Adapted from a post made by Kellen Mace.


Michael is a seasoned developer who loves helping build stuff for the internet. He brings over a decade of varied experiences working with both front and back end developer stacks.

His primary focus has been WordPress and PHP and all the components that go along with them. During the day, he is a Support Engineer with Maintainn and WebDevStudios, helping clients get the best that they can out of their own websites.

Categories: Web DevelopmentTags: , ,

8 thoughts on “Remove post type slugs from permalinks

  1. Hey Michael!

    It worked for me.. I used Code Snippet plugin to write the codes so i dont lose them after i update the theme. Just wondering what if i have multiple custom post types? What should the code look like?

    1. Probably need to amend this line:

      `if ( ‘movie’ === $post->post_type ) {` to do extra checks, and make sure to include all the ones you’re adding, to the query portion.

      `if ( ‘movie’ === $post->post_type || ‘tv_show’ === $post->post_type ) {`

  2. Hi Michael!

    I am recreating my WordPress tutorial web site and this time using the Custom Post Type UI (CPTUI) plugin where I made a CPT I called tutorials. As I am updating a bunch of older tutorials I would like to keep the same slug they have had for many years. This meant I had to remove the tutorials CPT slug. Using your tutorial I was able to remove the slug.

    Thank you!

  3. Hi Michael,
    I also need to remove the slug. I’m redesigning one page with Oxygen, so I decided to make a custom post type and ACF for products, which were in old version as pages. So because of SEO I would like to have same structure of slug http://www.page.xx/product. But when I use your code, slug is removed, but my Oxygen template isn’t applied anymore. Is there some advice please? Thanks.
    Tomas

    1. Very valid question, but I don’t have an answer about that. Oxygen support may be a better avenue to seek out some help from. I don’t have experience with their product.

  4. Hi Michael,

    The code works well to remove the slug, but I’ve been able to determine that it also causes an error in the Divi Theme Builder editor. Divi still works on regular pages, posts, etc, but throws an “unknown error” when you try to edit a template on the theme builder. Any ideas what might be causing this? (I identified it was this function by a process of elimination – I can reliably turn the theme builder on or off by simply cutting the function from my functions.php file). The site is also running CPT UI.

    Cheers,
    Ben

    1. Very sorry for the delay in response and comment approval here Ben.

      Admittedly, I do not have much of a lead on what may be causing this. To be clear, which of the functions is the issue? the one removing the slug from the permalink string? or the one affecting the post query? I’m guessing the latter, and I am wondering if Divi is expecting other post types included.

      Unsure if it’s possible with PHP to detect if Divi Frontend is enabled, but that’d be awesome if possible.

Leave a Reply

Your email address will not be published. Required fields are marked *

Webmentions