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.
Using %category% tag in your custom permalink structure
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:

/%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/$1Using 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.

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.

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:

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
I used quite some time to get this working on multiple custom taxonomies but here it is: (spot anything horrible in this?)
Thank you! I don’t usually comment on posts but after lots of searching and different solutions, this was the solution that I was looking for. Original post and also to aatospaja for the revised code for multiple taxonomies.
This is perfect multiple taxonomies fix. Thanks @aatospaja
I’m sorry I left some uneccesary code in there. I’d fix it if I could edit the comment. (namely, one can remove __NAMESPACE__ from filters and those taxnames are from a project I’m working on. Also, this code is based on the fact that the taxnames and slugs are the same and I removed some features that weren’t needed for my case. So basically my code isn’t a perfect here but it works…
You can create a new comment with the correct code, then I will replace the old one :)
Thanks for this – exactly what I was looking for.
Hi, very nice snippet, but there are few notice in wp_debug… http://prntscr.com/bvzumz
Coud you fixed it? Thanks
Hi,
Use
if( isset( ) )for each of the undefined indexes.Works like charm, thanks
My certain terms does not redirect and shows the attachement page.
Rudra what i found is the code does not handle the request to attachment page with the same url as that of any term.
Can you show me the screenshot of your permalinks settings?
Well it is set to
/%postname%/Everything should work then :) Maybe somewhere is an error or code conflict.
Hi! I found it doesn’t work when a taxonomy’s term slug contains within a slug of the taxonomy..
Hi, try to change
str_replace()function everywhere tostr_replace_first().And here it is:
Please, let me know if it works.
Thanks for your reply! URLs is ok now. But redirect cuts all the taxonomy slug name pieces from the URL until they’re all gone. As a result it’s Error 404.
Can you please describe me it more in details? On what pages this appears?
For example, I have a taxonomy with an argument ‘rewrite’
'rewrite' => array( 'slug' => 'cars', 'hierarchical' => true )This taxonomy contains a term with slug = “volvo_cars”, and this taxonomy term have a child term with slug = “sedan_cars”.
Without the last part of your code (redirect hook) it works perfectly, and when we wanna get to the “sedan_cars” page it looks like
http://domain.name/volvo_cars/sedan_cars/instead ofhttp://domain.name/cars/volvo_cars/sedan_cars/. Cool, it has no taxonomy “cars” slug and it contains “cars” in terms’ slugs and URLs .But if I turn the redirect hook on I get
http://domain.name/volvo_/sedan_/. It has no “cars” at all, it’s 404 page. Although all links on the site contains correct URLs (withount taxonomy “cars” slug only).Yes, your problem is clear for me now.
Yes, unfortunately this is how it works, but I know how to help you. First of make unique slug for your taxonomy.
Well, that’s all you need to do :) And change this slug everywhere in my code.
Nice decision :) I got it. Thanks a lot for your code and for your feedback!
You’re welcome! Subscribe to my blog :)
Thanks a lot! It works Great with the
/%postname%/Permalink Settings.But it don’t works with
/%category%/%postname%/Permalink Settings.Maybe you have any idea?
What taxonomy you are using? Category, post tag or a custom one?
Custom Category for posts
But as I see, your code does not remove the slug from the categories and tags in any format permalinks –
/%postname%/or/%category%/%postname%/.It works only for Custom Category with permalink settings
/%postname%/It is normal, if the code doesn’t work with
/%category%/%postname%/because for each permalink structure the code will be different!hmmm… I think I will update the code in this post later, adapt it for different permastructs.
How soon? Within a week I suppose, because it is not so simple.
Works for me, thanks from Lima – Perú.
Hi,
This ‘works’ but I’m getting this error in the error logs
[proxy_fcgi:error] [pid 5193] [client 127.0.0.1:58354] AH01071: Got error ‘PHP message: PHP Notice: Undefined index: attachment in ….
which is in this line
Any ideas why?
Hi,
you can try to replace this line with:
if( isset( $query['attachment'] ) && $query['attachment'] ) :.:) I thought the same. I’m not seeing an error now. Thanks for the reply.
Thanks for this amazing article; Any idea on how to remove custom post type slug from url?
Hi Roverd,
I have no ready code, but the ready algorithm is in this post.
Hey,
script seems to be nice. But in my case its not working with the grand-child terms /cat1/cat1b/term.
The URL rewrite works but if i try to enter the archive i get a 404.
Can you help me ?
Hey,
For each level of children, the code will be slightly different. You can contact me by email and I will try to help you with the code.
Hi, in my case I want to remove language slug like en_US (and more languages) from URL because they create som conflicts with some plugin functionnalities. I tryed your code but nothing happens.
https://www.mydomain.com/installation-folder/en_US (and fr_FR…)/…
Any advice?
Thank you very much
Hi, Misha
I got a problem when I was doing this. My url structure is like “http://domain.com/tax_name/term/child_term/child_term/”. I was trying to remove “tax_name” from url, It worked ok when I access the second level child terms, but when it’s “/term/” or “/term/child_term/”, the page showed with template “archive.php” instead of “taxonomy.php”.
Could you help me? Thank you very much.
Hi,
If you use child terms, the code will be different. Unfortunately I do not have the ready code to share it with you.
This work for the URL but then the 404 page is displayed when visiting the page.
Did you re-save your permalinks settings?
i did. i ended up removing the code and adding using
'slug'=>'/'in the rewrite attribute of my custom taxonomy and it worked perfectly.Misha – I am having the same issue that AJ is having. I have re-resaved my permalinks. I had this working last week and now it is no longer working. Any help would be greatly appreciated.
i found a solution. see below.
Hmmm… I will try to check it when I have time.
my solution actually did not work. it breaks the permalinks for other pages. can you help me trouble shoot this solution?
I found a solution:
Nice job AJ, this worked for me. FINALLY!
Hello Misha, I have problems with subterms links pagination, they show 404 page.
www.site/sherry-activities/diy-projects/page/2/ – not found
www.site/advice_cat/sherry-activities/diy-projects/page/2/ – works
Could you help me with it?
you saved my life. now i’ve got a new follower
Can you please confirm how to remove the ‘tag’ from the URLs. I have tried many different variations of the code above and unfortunately I cannot get it to work.
I only want to remove the mywebsite.com/tag/spain from my URL. how is this done?
Thanks
Hey Adam,
Hmm.. It should work the same way for post tags.
Thank you very much.
I almost spent couple of hours for solution and finally got it done using this code.
Great job. Keep it up :)