How to Remove the Product-Category Slug in WordPress WooCommerce
This WordPress WooCommerce fix will allow you to remove the product-category slug from the URL in WordPress WooCommerce without using a plugin.
Example:
From: https://mywebshop.com/shop/product-category/apparel/black-pants
To: https://mywebshop.com/shop/apparel/black-pants
Remove the product-category slug from the WordPress WooCommerce URL
1. Add this snippet to the functions.php file in your WordPress theme.
add_filter('request', function( $vars ) { global $wpdb; if( ! empty( $vars['pagename'] ) || ! empty( $vars['category_name'] ) || ! empty( $vars['name'] ) || ! empty( $vars['attachment'] ) ) { $slug = ! empty( $vars['pagename'] ) ? $vars['pagename'] : ( ! empty( $vars['name'] ) ? $vars['name'] : ( !empty( $vars['category_name'] ) ? $vars['category_name'] : $vars['attachment'] ) ); $exists = $wpdb->get_var( $wpdb->prepare( "SELECT t.term_id FROM $wpdb->terms t LEFT JOIN $wpdb->term_taxonomy tt ON tt.term_id = t.term_id WHERE tt.taxonomy = 'product_cat' AND t.slug = %s" ,array( $slug ))); if( $exists ){ $old_vars = $vars; $vars = array('product_cat' => $slug ); if ( !empty( $old_vars['paged'] ) || !empty( $old_vars['page'] ) ) $vars['paged'] = ! empty( $old_vars['paged'] ) ? $old_vars['paged'] : $old_vars['page']; if ( !empty( $old_vars['orderby'] ) ) $vars['orderby'] = $old_vars['orderby']; if ( !empty( $old_vars['order'] ) ) $vars['order'] = $old_vars['order']; } } return $vars; });
2. Enter a “.” in the “product category base” field on the permalinks settings page (wp-admin/options-permalink.php).

Enter a “.”in the “product category base” field.
3. Save to flush the rewrite rules.
Thank You, finally a solution that actually works 🙏
+1
Nooo it’s not working. Just throwing 404 error.
Unfortunately it did not work for me.
It trows a 404 page.
Did you remember to re-save your permalinks after you added the snippet?
*also, try and check your caching plugins and your htaccess to see if there are any conflicts in the rewrites?
If you’re doing this for SEO, look at the source, although hovering over the links show a perfectly formed url, many of the instances in source still have the url formed as
http://url.tld/./whatver
Hi Thank you for this trick.
Is-t possible to remove “Shop” in product permalink ?
Best regards,
Julien
Really thanks.
Thank you so much! It is working fine.
Do you also have the snippet for removing the “product” slug for Woocommerce products and the “product-tag” slug for tags?
+1
+1
it works but when it goes to the 3rd subcategory it is 404 error like only works on /baby/baby-girl-clothing/ then its 404 error on /baby/baby-girl-clothing/sets-baby-girl/
I can confirm this bug – only works for top-level categories
add_filter( ‘term_link’, ‘devvn_product_cat_permalink’, 10, 3 );
function devvn_product_cat_permalink( $url, $term, $taxonomy ){
switch ($taxonomy):
case ‘product_cat’:
$taxonomy_slug = ‘product-category’; //Product category base is product-category
if(strpos($url, $taxonomy_slug) === FALSE) break;
$url = str_replace(‘/’ . $taxonomy_slug, ”, $url);
break;
endswitch;
return $url;
}
// Add our custom product cat rewrite rules
function devvn_product_category_rewrite_rules($flash = false) {
$terms = get_terms( array(
‘taxonomy’ => ‘product_cat’,
‘post_type’ => ‘product’,
‘hide_empty’ => false,
));
if($terms && !is_wp_error($terms)){
$siteurl = esc_url(home_url(‘/’));
foreach ($terms as $term){
$term_slug = $term->slug;
$baseterm = str_replace($siteurl,”,get_term_link($term->term_id,’product_cat’));
add_rewrite_rule($baseterm.’?$’,’index.php?product_cat=’.$term_slug,’top’);
add_rewrite_rule($baseterm.’page/([0-9]{1,})/?$’, ‘index.php?product_cat=’.$term_slug.’&paged=$matches[1]’,’top’);
add_rewrite_rule($baseterm.'(?:feed/)?(feed|rdf|rss|rss2|atom)/?$’, ‘index.php?product_cat=’.$term_slug.’&feed=$matches[1]’,’top’);
}
}
if ($flash == true)
flush_rewrite_rules(false);
}
add_action(‘init’, ‘devvn_product_category_rewrite_rules’);
/*Sửa lỗi khi tạo mới taxomony bị 404*/
add_action( ‘create_term’, ‘devvn_new_product_cat_edit_success’, 10, 2 );
function devvn_new_product_cat_edit_success( $term_id, $taxonomy ) {
devvn_product_category_rewrite_rules(true);
}
//
This works great for the most part, and I could adapt it for other custom taxonomies as well. Two-level categories work too (for example: site.com/category/subcategory).
However, pagination will break if you are in sub categories. Root categories will have working pagination, but sub categories will not. So site.com/category/page/2 will work; site.com/category/subcategory/page/2 will return a 404 error.
Something must be happening up in the wordpress filter chain, because by the time you hit the ‘request’ filter, the request variables already only state the 404 error.
Thank You, that actually works
not done with above solution
Works great in the first 2 out of these 3 scenarios:
1. When there is only one product in a category and you are on that product page you get “domain/shop/category/product”. (I have a snippet that takes you right to the product page when you click on a category that only has one product.)
2. When there are multiple products in a category and you are on a product page you get
“domain/shop/category/product”.
3. But when you are on a category page with multiple products in that category, you get
“domain/product-category/category”.
What we want to see would be “domain/shop/category”
Any ideas on how to keep the beauty of #1 and 2, but fix #3?
Hey,
It works but in the sitemap generated by yoast seo -> category_product sitemap i can see links with dot:
examle-website.com/./name and i can still access site with “product-category” in url…
so now we have to URLs
1. example-website.com/category-product/name
2. example-website.com/name
and in the generated sitemap we have: example-website.com/./name
Now we have duplicated content and bad url in the sitemap.
any solutions to this?
Hi Krystian,
We are facing the exact same problem.
Have anyone found a solution to this?