Issue with woocommerce parent child category url

In WooCommerce, child categories have the following URL structure: site.com/product-category/parent-category/child-category. However, if I modify the "parent-category" part of the URL in the browser, like this: site.com/product-category/parenwqewqt-qwecategory/child-category, the page still returns a 200 status code instead of a 404, even though the URL is incorrect. This seems to be a common WooCommerce issue that could lead to SEO problems, as invalid URLs are not properly flagged as 404 errors. I tried to create a hook to fix this, but it didn't work. Here's the code I used: I create this but nothing changes: add_action('template_redirect', 'custom_woocommerce_category_404'); function custom_woocommerce_category_404() { if (is_product_category()) { $category = get_queried_object(); if (!$category || !term_exists($category->slug, 'product_cat')) { global $wp_query; $wp_query->set_404(); status_header(404); nocache_headers(); include(get_query_template('404')); exit; } } } How can I modify this or create a proper hook to return a 404 error when the URL structure is incorrect?

Comment (1)

Jese Leos

September 17, 2024

Verified user

WooCommerce category URLs return a 404 error when the parent category in the URL is incorrect. It hooks into the template_redirect action to check if a product category is being viewed. If the category exists and has a parent, it compares the parent slug in the URL with the actual parent category of the current child category. The function get_parent_category_from_url() extracts the parent slug from the URL, and if it doesn't match the actual parent category in the database, it triggers a 404 error using set_404(). Try the following: // Hook into template redirect to modify WooCommerce category URL handling add_action('template_redirect', 'custom_woocommerce_category_404'); /** * Custom function to trigger a 404 error if the WooCommerce category URL structure is invalid. * This checks if the parent category in the URL is correct for the given child category. */ function custom_woocommerce_category_404() { if (is_product_category()) { // Get the current queried category object $category = get_queried_object(); // If the category doesn't exist, trigger a 404 error if (!$category || !term_exists($category->slug, 'product_cat')) { handle_404(); } // Check if the current category has a parent category and if the URL structure is correct if (is_tax('product_cat') && get_query_var('product_cat')) { $current_cat_slug = get_query_var('product_cat'); $current_cat = get_term_by('slug', $current_cat_slug, 'product_cat'); // If the current category has a parent, compare it with the URL structure if ($current_cat && $current_cat->parent != 0) { $parent_cat = get_term($current_cat->parent, 'product_cat'); // Extract the parent category slug from the URL $requested_parent_slug = get_parent_category_from_url(); // If the parent slug in the URL doesn't match the actual parent, trigger a 404 error if ($requested_parent_slug && $requested_parent_slug !== $parent_cat->slug) { handle_404(); } } } } } /** * Helper function to extract the parent category from the URL, ignoring pagination. * This works by splitting the URL path and retrieving the second-to-last part before 'page'. */ function get_parent_category_from_url() { global $wp; $url_path = $wp->request; // Get the current request URL path $parts = explode('/', $url_path); // Remove pagination part (e.g., 'page/2') if it exists $pagination_index = array_search('page', $parts); if ($pagination_index !== false) { $parts = array_slice($parts, 0, $pagination_index); } // Return the second last part of the URL (which should be the parent category slug) return (count($parts) > 2) ? $parts[count($parts) - 2] : null; } /** * Helper function to handle triggering a 404 error. * This includes setting the 404 header, including the 404 template, and exiting. */ function handle_404() { global $wp_query; $wp_query->set_404(); status_header(404); nocache_headers(); include(get_query_template('404')); exit; } This is a tested and working solution.

You’ll be in good company