How to Remove a Taxonomy Slug from URL

In this tutorial we’re going to talk a little bit about rewriting taxonomy URLs in WordPress. I am about to show you different examples of how you can remove a custom taxonomy slug from a URL (and “category” in particular, because it works a little bit differently).

But first of all – a disclaimer. When you rewrite any kind of URL in WordPress, you should keep in mind that it was not supposed to work that way, which means that you need to spend extra time testing the end result.

For example, let’s say your website posts have URLs like your-site/post-name but what will happen if you want your categories to look the same, your-site/category-name? How is WordPress supposed to figure out the difference? Do you get my point, don’t you?

Remove “category” from WordPress URLs

The thing with rewriting taxonomy URLs is that it depends on a permalink structure which you set in Settings > Permalinks. That’s actually the reason why we need to take a look at different ways of removing “category” from URLs over here.

Let’s do that.

I think this way is the best because you don’t need to use any plugins or custom code – it just kind of works by default.

So, let’s try it out, let’s open the Permalinks settings page and set something like this there:

Custom permalink structure with a category tag.
You can also use something like /%category%/%postname%.html, for example.

Once you do that and hit the “Save changes” button, your category pages are going to be available by both your-site/category/category-name and your-site/category-name. Since we have duplicated pages right now, we need to set up a 301 redirect. In order to do so just use the line below in your .htaccess file:

RedirectMatch 301 /category/(.*) https://your-site/$1

Using a plugin from the WordPress repository

If you have a permalink structure other than /%category%/..., then the only easy way to remove “category” from URLs is to use a plugin for that. There are plenty of plugins out there that allow you to have this functionality as a part of a whole, for example, Yoast SEO.

Remove category from WordPress URLs with Yoast SEO plugin
In order to remove a category base with the help of the Yoast SEO plugin, you need to go to the plugin settings, then to the “Categories & tags” section, and scroll to the Additional settings.

Other big SEO plugins like, let’s say, RankMath SEO, also allow you to do that.

But if you’re considering a small plugin for this purpose specifically, I would like to recommend you take a look at “No Category Base” plugin, which is free and available both in your WordPress admin and in the plugin repository.

No category base WordPress plugin

If you’re looking for the code approach, just keep reading this tutorial, below you will find the code which allows you to rewrite taxonomy URLs (and categories, guess what is also a taxonomy)

Remove a Custom Taxonomy Slug from URLs

Right now, let’s talk about the code approach, which basically allows you to rewrite taxonomy URLs in WordPress any way you like.

Below is the main part of the code, you can insert it into your current theme functions.php, just do not forget to change taxonomy names/slugs in each function to your own values.

The code consists of two functions:

  • rudr_change_term_request() / request – here, when a taxonomy term page is opened, we check if it is really a term page and tell WordPress that,
  • rudr_term_permalink() / term_link – this function removes a taxonomy slug from URLs of WordPress custom taxonomy terms.

So, here we go:

add_filter( 'request', 'rudr_change_term_request', 1, 1 );

function rudr_change_term_request( $query ){

	$tax_name = 'product_cat'; // specify your taxonomy name here, it can be also 'category' or 'post_tag'

	// Request for child terms differs, we should make an additional check
	if( $query[ 'attachment' ] ) {
		$include_children = true;
		$name = isset( $query[ 'attachment' ] ) ? $query[ 'attachment' ] : '';
	} else {
		$include_children = false;
		$name = isset( $query[ 'name' ] ) ? $query[ 'name' ] : '';
	}

	$term = get_term_by( 'slug', $name, $tax_name ); // get the current term to make sure it exists

	if( ! is_wp_error( $term ) && $term ) {
		// let's not forget about hierarchical taxonomies
		if( $include_children ) {
			unset( $query[ 'attachment' ] );
			$parent = $term->parent;
			while( $parent ) {
				$parent_term = get_term( $parent, $tax_name );
				$name = "{$parent_term->slug}/{$name}";
				$parent = $parent_term->parent;
			}
		} else {
			unset( $query[ 'name' ] );
		}

		switch( $tax_name ) {
			case 'category' : {
				$query[ 'category_name' ] = $name; // for categories
				break;
			}
			case 'post_tag' : {
				$query[ 'tag' ] = $name; // for post tags
				break;
			}
			default : {
				$query[ $tax_name ] = $name; // for other taxonomies
				break;
			}
		}
	}

	return $query;

}

add_filter( 'term_link', 'rudr_term_permalink', 10, 3 );

function rudr_term_permalink( $url, $term, $taxonomy ){

	$taxonomy_name = 'product_cat'; // your taxonomy name here
	$taxonomy_slug = 'product_cat'; // the taxonomy base slug can be different with the taxonomy name (like 'post_tag' and 'tag' )

	// exit the function if this taxonomy slug is not in the URL
	if( false === strpos( $url, $taxonomy_slug ) || $taxonomy !== $taxonomy_name ) {
		return $url;
	}
	
	// remove taxonomy base slug from term links
	$url = str_replace( '/' . $taxonomy_slug, '', $url );

	return $url;

}

Once done, don’t forget to refresh the permalinks cache. You can do it by simply going to the Permalinks settings and hitting the “Save changes” button even without changing anything.

And do not forget about 301 redirect from old URLs, it is required for your website SEO.

add_action( 'template_redirect', 'rudr_old_term_redirect' );

function rudr_old_term_redirect() {
	
	$taxonomy_name = 'product_cat';
	$taxonomy_slug = 'product_cat';
	
	// exit the redirect function if taxonomy slug is not in URL
	if( false === strpos( $_SERVER[ 'REQUEST_URI' ], $taxonomy_slug ) ) {
		return;
	}

	if( is_tax( $taxonomy_name ) ) {
		// remove taxonomy base slug and redirect
		wp_safe_redirect( site_url( str_replace( $taxonomy_slug, '', $_SERVER[ 'REQUEST_URI' ] ) ) );
		exit;
	}

}

The code was tested with different hierarchical and non-hierarchical taxonomies and with the “Post name” permalinks settings:

optimal permalink settings when removing taxonomy slug from url in WordPress
Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X