How to Best Remove the Word “Category” from the Permalink (URL) in WordPress

In general, I do not recommend to remove the word "category" from WordPress URLs, as this can cause problems and there is no practical benefit to doing so. But if for some reason you decide to do it, I hope this article will help you.

I am not a fan of tweaking with the settings for Pretty Permalinks, so in most cases, I am neutral about them - the main thing is that the title of the article is present in the URL in transliteration for Cyrillic titles. I believe that the article titles are generally sufficient for orienting where the URL leads. By the way, I do not support the practice of translating words into English, because not everyone knows English, and such (translated) URLs will not be clear to many users.

I recently needed to remove the word "category" from the URLs of category pages. URLs for category pages usually look like this:
/category/parent-category-name/child-category-name

Plugins

The theme of removing category from the URL is not new and, as it turns out, has long been discussed on many blogs and forums. There are already several good plugins for this purpose:

  1. No Category Base (WPML) removes the category base from the category permalinks.

  2. No category parents - the plugin removes the category base that is set in the admin panel (it may be different from "category"). For it to work, the URL structure can be any. It is said that the plugin does not always work (probably depends on the URL structure). The advantage of this plugin is the installation of a 301 redirect (needed for search engines when the word "category" is removed from an already existing website/blog).

  3. Remove Parents - The plugin works only if the URL structure starts with the tag %category%. I didn't like the author's approach to the plugin - for some reason they use regular expression checks when all that is needed is to remove the word "category". However, this plugin not only removes the word "category" but also the parent categories from the post URLs (which may be necessary in certain cases).

My Solution

Does not work correctly from version 4.0

In general, I did not like the plugins, and for such a task, a plugin is unnecessary. Therefore, I wrote my own hack to remove "category" from the category page permalinks in WordPress (it's just one line):

// Remove category from category URL
add_filter( 'category_link', function($a){
	return str_replace( 'category/', '', $a );
}, 99 );

This line of code needs to be added to the theme's functions.php file. Also, the URL structure should start with /%category%/ and the category prefix should NOT be set in the permalink settings in the admin panel (see image). If the category prefix is already set, simply remove it, but remember this prefix for setting up redirects (see the hack below).

For those who prefer retro: in old versions of WP, I also inserted "category" into post URLs, to remove this word from there, use this line:

add_filter( 'post_link', function($a){
	return str_replace( 'category/', '', $a );
}, 99 );

Removing Category via .htaccess

There is another option involving editing the .htaccess file. In this file, you need to add a 301 redirect, it looks like this:

RewriteRule ^(.*?/)category/(.+)$ $1$2 [R=301,L]

It is important to understand that this line should be inserted after enabling the mod_rewrite module and before the WordPress redirect itself, that is, it should be placed like this:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(.*?/)category/(.+)$ $1$2 [R=301,L]
</IfModule>

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Do not insert this rule between WP rules BEGIN WordPress ... # END WordPress, because it will be wiped out at some point when regenerating htaccess rules. See the mod_rewrite_rules hook where such a rule can be added systematically.

However, this method has its drawbacks; it only works if the URL structure starts with /%category%/ and WordPress will still create category links with the word "category", simply redirecting the user to a link without "category" upon clicking such a link. But I think this option is still very much viable.

Poor Option

As an alternative, in versions of WordPress 3.0+, you can avoid using any hacks or plugins and simply insert a dot in the Category base field. This can be done in the WordPress admin panel on the Settings > Permalinks page (see image). However, this dot will be in the URLs in the HTML code, which may not be ideal, but it seems to work correctly.

301 Redirect Hack

Additionally, I have created a hack to redirect old pages (with the "category" word) to the new ones. The redirect is a 301 status - an indication that the page has been permanently moved (needed for search engines). This is essentially what the aforementioned line for .htaccess does.

add_action( 'init', 'base_category_redirect', -10 );

function base_category_redirect() {
	$uri = $_SERVER['REQUEST_URI'];
	$cat_prefix = 'category';

	if( strpos( $uri, "/$cat_prefix/" ) !== false ){
		$new_url = home_url( str_replace( "/$cat_prefix/", '/', $uri ) );
		wp_redirect( $new_url, 301, 'category_redirect' );
		exit;
	}
}

If you have set a category prefix in the admin panel, you need to specify this prefix in the code.

By the way, for those who do not know why a category prefix is needed at all: it is needed to clearly define the type of page. Imagine a situation where we removed this prefix, and we have a static page with the title "Miscellaneous" (with the slug "miscellaneous") and a category with the same name, then the URLs of the category and the page will be the same and will be equal to http://example.com/miscellaneous, which will make it impossible to access the category page because the static page will be opened using this URL. On the one hand, this is not good, but on the other hand (eureka!), this feature can be very conveniently used to replace the category page with a static page. Sometimes it is necessary for a category page to not display the usual posts or post excerpts, but to show some text instead. I think the logic is clear...

Summary of the Above

The best option, in my opinion, to remove the word "category" will be placing the following code in the theme's functions.php file (only works if the URL structure starts with /%category%/):

add_filter( 'category_link', function( $a ){
	return str_replace( 'category/', '', $a );
}, 99 );

Also, if the blog is not new and search engine indexes already have pages with "category", then in addition to the code, a redirect line needs to be added to .htaccess:

RewriteRule ^(.*?/)category/(.+)$ $1$2 [R=301,L]

If the URL structure does not use the %category% tag (does not start with /%category%/), use the WP No Category Base plugin.

If something is unclear, feel free to ask, the comments are open smile