Remove Custom Taxonomy Base

The question:

I am using custom taxonomies with WordPress 3.0.4

I am wondering if anyone knows how to remove the taxonomy base from the URL?

I have seen plugins that do it for categories and tags, but not for custom taxonomies.

For example, I have a custom taxonomy called ‘cities’. I would like my URL structure to be instead of

Is there a function or something I can use?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I think this is possible, but you will need to keep an eye on the order of the rewrite rules. To help you with this I recommend a plugin I wrote to analyze the rewrite rules (soon available in the repository, but you can download a pre-release).

First of all, these rules are quite generic, and should thus come at the end of the rules list. The default action is to put them at the top, so we prevent the default and add them ourselves. We already have the generic page rules at the bottom, so we should make them explicit and move them to the top by enabling verbose page rules. This is not efficient when you have lots of pages, but I don’t think there is another way to do it now.

add_action( 'init', 'wpse6342_init' );
function wpse6342_init()
    // Register your taxonomy. `'rewrite' => false` is important here
    register_taxonomy( 'wpse6342', 'post', array(
        'rewrite' => false,
        'label' => 'WPSE 6342',
    ) );

    // Enable verbose page rules, so all pages get explicit and not generic rules
    $GLOBALS['wp_rewrite']->use_verbose_page_rules = true;

add_action( 'generate_rewrite_rules', 'wpse6342_generate_rewrite_rules' );
function wpse6342_generate_rewrite_rules( &$wp_rewrite )
    // This code is based on the rewrite code in `register_taxonomy()`

    // This rewrite tag (%wpse6342%) is just a placeholder to use in the next line
    // 'wpse6342=` should be the same as the `query_var` when registering the taxonomy
    //    which is the name of the taxonomy by default
    // `(.+?)` works for a hierarchical taxonomy
    $wp_rewrite->add_rewrite_tag( '%wpse6342%', '(.+?)', 'wpse6342=' );
    // This will generate the actual rewrite rules, and put the at the end of the list
    $wp_rewrite->rules += $wp_rewrite->generate_rewrite_rules( $wp_rewrite->front . '%wpse6342%', EP_NONE );

Method 2

Rewriting the slug (-> to empty) within the taxonomy registration won’t work so I’m not sure what other options you have within WordPress. You’ll probably need to modify the .htaccess directly to fit your needs.

However, a word of caution to this permalink setup; Otto describes the issue quite well here: .



Method 3

I tried the WP No Taxonomy Base plugin mentioned by the plugins author and it did not work for me. At first I was optimistic it would do the trick, but then I noticed all site permalinks continued to retain the base slug. It was only after navigating to one of the link destinations the base slug was removed, but it remained persistent in all site permalinks, which kind of defeats the purpose.

I have heard some people have had success doing what it sounds like you would like to do using the WP htaccess Control plugin. Its author lists the following features:

  • Customizing the htaccess file generated by WordPress;
  • Removing any custom taxonomy’s slug base from permalinks;
  • Removing the category base from permalinks;
  • Removing the author base from permalinks;
  • Customizing the Author Permalink Base;
  • Customizing Paginated Permalinks (translate the “page” word on permalinks to your own language);
  • Customization (and canonization) of the Search Permalink Base;
  • Creation of Category, Author, Tag and Custom Taxonomy based archives (ex: “”, “” and “”), this will also work if you’ve removed the base slug;
  • Maintenance mode;
  • wp-login.php redirection.

I personally experienced problems getting the plugin to save my new settings both times I tried it. It wanted to connect to “https” instead of “http” on save and would throw an error when it could not. However, maybe you will have better luck!

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment