Skip to content

WooCommerce category page SEO: what a product category tells Google, its pagination and its address

With no SEO plugin, a WooCommerce category page prints its name as title and heading, your description and a breadcrumb trail, and no canonical link or meta description. Its pagination is set out as Google asks. What it lacks is words for the shopper and links from the rest of the store.

By
WP Ministry
Published
Tested on
WordPress 7.1.3, WooCommerce 11.2.0, PHP 8.3.35

In short

  • A category page prints its name as title and h1, your description, and a breadcrumb trail with BreadcrumbList data. It prints no meta description, no canonical link and no product data.
  • Each later page has its own address and "Page 2" in its title, and a page number past the end answers 404. Google's pagination guidance asks for that, and for a canonical link on each page.
  • Google says not to make the first page the canonical of the pages after it, and that it no longer uses rel="next" and rel="prev".
  • On a new store nothing links to a category except its own products. Google reads what matters on a site from its links, so the menu comes first.
  • An empty category answers 200 with "No results found". WordPress keeps it out of the sitemap until it holds a product.
  • Changing the product-category base moves every category and leaves the old addresses answering 404. Emptying the field does not remove the base.

With no SEO plugin, a WooCommerce product category page gives a search engine its own address, a title and a heading made from the category's name, the description you typed for the category, a breadcrumb trail, and a line in WordPress's sitemap. Each later page of the category has its own address, which is what Google's pagination guidance asks for. The page has no meta description, no canonical link and no product data, and on a new store nothing links to it except its own products.

For a search for a kind of product, the category page is often the right answer, and most of what makes it worth finding is not a tag. It is a description written for the shopper, a name that says what the range is, and links from the menu. This page shows what a category prints today, sets that beside Google's documentation, and deals with the product-category in its address.

What a category page prints

These were read from a test store on WordPress's default theme, with Post name permalinks and no SEO plugin. It has a category named Kettles with a description and twenty products, a subcategory of it named Stovetop, and an empty category named Gift sets. The list showed sixteen products to a page, so Kettles has two pages.

First pageSecond page
Address/product-category/kettles//product-category/kettles/page/2/
Status200200
<title>The category's name, then the site's nameThe same, with "Page 2" between them
<h1>KettlesKettles
The category's descriptionUnder the headingUnder the heading again
Meta descriptionNoneNone
Robots tagmax-image-preview:largemax-image-preview:large
Canonical linkNoneNone
rel="next" or rel="prev" linkNoneNone
Breadcrumb trailHome / KettlesHome / Kettles / Page 2
Structured dataA BreadcrumbList, and nothing elseThe same, with "Page 2" as its third item
In wp-sitemap-taxonomies-product_cat-1.xmlYesNo

What to take from it:

  • The robots tag blocks nothing. max-image-preview:large allows large image previews. Neither page has noindex.
  • There is no canonical link. WordPress prints one on a single post, page or product, and WooCommerce adds none to a list. What that means for the sorted and filtered copies of the page is covered in WooCommerce filter URLs in Google.
  • The description is on every page of the category. WooCommerce's template for block themes prints it with WordPress's Term Description block, which does not look at the page number. The function WooCommerce's classic templates use prints it on the first page only. So this row depends on your theme.
  • The only structured data is the breadcrumb trail. There is no Product data and no list of the products, which is as Google wants it (see below).
  • A subcategory sits under its parent. Stovetop is at /product-category/kettles/stovetop/, with its own title, the trail Home / Kettles / Stovetop, and its own line in the sitemap.

A theme or an SEO plugin changes this table, so read your own store's. This prints the title, the robots tag and the canonical link of one address, as a crawler receives them:

bash
curl -s https://example.com/product-category/kettles/ | grep -i -o -E '<title>[^<]*</title>|<(link|meta)[^>]*(canonical|robots)[^>]*>'

On the test store it prints two lines. A third, beginning <link rel="canonical", means something on your store adds a canonical link.

text
<meta name='robots' content='max-image-preview:large' />
<title>Kettles &#8211; Example Store</title>

In the page's source the dash is written &#8211;. Run it again with page/2/ on the end of the address.

Pagination, beside Google's guidance

This is what Google's page on pagination for ecommerce sites asks, and what the test store does.

Google's guidanceThe test store
Give each page of a list its own URL/page/2/ after the category's address
Link each page to the next with an <a href> link, and consider linking every page back to the firstThe page links are ordinary links. Page 2 links back to the plain category address, not to a /page/1/
Do not use the first page as the canonical of the others. Give each page its own canonical URLNo page has a canonical link, so none points at page 1, and none names itself
Pages in a sequence may share one title and descriptionThe store adds "Page 2" to the title anyway
Google no longer uses rel="next" and rel="prev", though other search engines mayNeither is printed

A page number past the end, /product-category/kettles/page/3/ here, answers 404 with the title "Page not found".

Two things often said about pagination are not on Google's page. It does not ask for a "view all" page. And it does not say to put noindex on page 2 and later: the only noindex it mentions is for sorted or filtered copies of a list.

That leaves one line the store does not meet, a canonical link on each page. Google's page on URL structure for ecommerce asks for a self-referencing canonical link on every indexable page. Its page on canonical links also says a site will likely do fine without one, because Google then chooses the address itself. So the next section is optional.

An SEO plugin does this. Without one, a must-use plugin can: one PHP file in wp-content/mu-plugins/, which WordPress loads on every request with nothing to activate.

  1. Step 1: Check that nothing prints one already

    Run the command above. If it prints a <link rel="canonical" line, stop here: Google's documentation says not to name different canonical addresses for one page by different means.

  2. Step 2: Create the mu-plugins folder if it is not there

    Look in wp-content. If there is no folder named mu-plugins, create one.

  3. Step 3: Add the file

    Save this as category-canonical.php in that folder.

    wp-content/mu-plugins/category-canonical.php
    <?php
    /**
     * Plugin Name: Category canonical links
     * Description: Gives each page of a product category a canonical link to its own address.
     */
    
    add_action(
    	'wp_head',
    	function () {
    		global $wp_rewrite;
    
    		if ( ! function_exists( 'is_product_category' ) || ! is_product_category() ) {
    			return;
    		}
    
    		$url = get_term_link( get_queried_object() );
    		if ( is_wp_error( $url ) ) {
    			return;
    		}
    
    		$page = (int) get_query_var( 'paged' );
    		if ( $page > 1 && $wp_rewrite->using_permalinks() ) {
    			$url = user_trailingslashit( trailingslashit( $url ) . $wp_rewrite->pagination_base . '/' . $page, 'paged' );
    		} elseif ( $page > 1 ) {
    			$url = add_query_arg( 'paged', $page, $url );
    		}
    
    		echo '<link rel="canonical" href="' . esc_url( $url ) . '" />' . "\n";
    	}
    );
  4. Step 4: Read the first page and the second

    Run the command again. It now prints three lines.

    text
    <meta name='robots' content='max-image-preview:large' />
    <title>Kettles &#8211; Example Store</title>
    <link rel="canonical" href="https://example.com/product-category/kettles/" />

On /product-category/kettles/page/2/ the link ends in /page/2/, so each page names itself. A sorted address such as /product-category/kettles/?orderby=price names the plain page it is a copy of. A page number past the end still answers 404 and gets no link, and the shop page is left as it was.

The file is listed on the Plugins screen under "Must-Use". To undo the change, delete it.

An empty category

Gift sets has a description and no products. Its address answers 200 with its title, its heading and its description, the words "No results found" where the products would be, and the same robots tag as any other page. WordPress leaves it out of the sitemap, which lists only categories with something in them. When one product was put in it, it was in the sitemap on the next request.

A new store starts with one of these, the category named Uncategorized. On the test store /product-category/uncategorized/ answered the same way.

Google's URL structure page says to avoid linking to pages without useful content, or at least indexing them. For a category with no items it suggests a noindex robots tag, or a 404 where a site takes its empty categories out of browsing by itself. WooCommerce does neither. So put products in the category, delete it, or keep it out of the menu until it has some.

The product-category in the address

The word is the category base. It is set under Settings, then Permalinks, in the section headed "Optional", in the field "Product category base", and WooCommerce keeps it in an option named woocommerce_permalinks. With WP-CLI, this prints it:

bash
wp option pluck woocommerce_permalinks category_base

On a store that has never changed it, the answer is product-category.

What changing it does

On the test store the base was changed to range. The second half of this command rebuilds WordPress's list of addresses, which saving the Permalinks screen does for you.

bash
wp option patch update woocommerce_permalinks category_base range && wp rewrite flush
  • The categories moved at once. /range/kettles/, its page 2 and /range/kettles/stovetop/ answered 200. The sitemap and the links on product pages gave the new addresses.
  • Every old address answered 404. /product-category/kettles/ and everything under it. Nothing forwards them.
  • Unless WordPress guesses. For some missing addresses, WordPress looks for a post, page or product whose slug begins with the same word, and redirects to it. After a product named "Kettles gift box" was added, /product-category/kettles/ answered with a 301 to that product's page. An old category address can end up at one product that happens to share its first word.

So a changed base needs a redirect for the whole old pattern, added in the same sitting. Changing permalinks without breaking old links shows such a rule and how to test it. To go back, run the same command with product-category in place of range.

Taking it out altogether

The field cannot do it. Emptied on the test store, it went back to product-category: WooCommerce reads an empty base as the default one.

Removing the base takes a plugin, and WooCommerce's developer documentation advises against it. WordPress uses the base to tell that an address belongs to a product category, and an ordinary page has no base at all, so /kettles/ could be either. It says plugins that remove the base can cause problems with performance and duplicate URLs.

Whether the word matters to Google

Google's page on ecommerce site structure says it generally does not look at the structure of URLs to work out the structure of a site. It reads the links between pages. Its URL structure page says descriptive words in a path may help it understand a page, and its example sets a product's name against a product's number. In /product-category/kettles/ the descriptive word is kettles, with the base or without it. Neither page says a fixed word before the category's name counts against it.

So the base is cosmetic, changing it breaks every category address the store has, and WooCommerce advises against removing it. Leave it alone unless the addresses are changing anyway.

What makes a category page worth finding

A description written for the shopper

The description is the "Description" box under Products, then Categories. WooCommerce's documentation says only that some themes display it. The default theme prints it under the heading.

It is the only prose on the page. Google's documentation on snippets says a snippet is made primarily from the page's own content, and may come from a meta description when that describes the page better. A category page has no meta description, so the description and the products' names are what there is.

Write what a shopper standing in front of the shelf would ask: what the range is, how the products differ, how to choose between them, and anything true of all of them, such as sizes, materials or delivery. Do not write a list of search terms. Google's spam policies define keyword stuffing as "filling a web page with keywords or numbers in an attempt to manipulate rankings".

A name that says what the range is

The title and the heading are both the category's name. Google's title link documentation asks for a descriptive, concise title that differs from page to page, and says it reads the <title> and the page's main heading when it builds the link. So the name is the lever: "Kettles", not "Range 2". WooCommerce has no separate field for a category's title.

On the test store the home page and the shop page linked to no category at all, and the Kettles page did not link to Stovetop. The only links to a category were on its products' pages: the breadcrumb trail and the category line.

Google's site structure page asks for the opposite: links from menus to category pages, from category pages to subcategories, and from there to every product. As a general rule, it says, the more links a page has from within a site, the more important it looks beside the site's other pages. So add your main categories to the navigation menu, and link subcategories from their parent. On a classic theme, "Category display" under Appearance, Customize, WooCommerce, Product Catalog can show subcategories above the products. WooCommerce's documentation says block themes do not use the Customizer, so there the links come from the menu or a block added to the template.

The breadcrumb trail

WooCommerce prints the trail and the matching BreadcrumbList data by itself, on categories and on products. Google's documentation says it uses breadcrumb markup to categorize a page in search results, on desktop. There is nothing to add.

Product data stays on product pages

Google's product documentation says product rich results support only pages that focus on a single product, and recommends marking up product pages, not pages that list a category of them. Its carousel markup, ItemList, is for courses, movies, recipes and restaurants. What a product page should carry is in WooCommerce schema markup.

How many products to a page

Google's pagination page gives the reasons to split a long list: a faster first load and less work for the server. On a classic theme the number is "Products per row" times "Rows per page" in the same Customizer panel. See speeding up a WooCommerce store.

What an SEO plugin adds here

Mostly the canonical link. Yoast SEO's published specification, for one, puts a canonical link on every indexable page, list pages included, keeps the page number in it and takes sorting and filtering queries out. That is what the file above does. If you run such a plugin, do not add the file as well.

When to get help

  • Ask the theme's support if the description or the breadcrumb trail does not appear on your category pages.
  • Hand it over if the store's own output does not match this page and you cannot tell what changes it. WooCommerce SEO from WP Ministry is search work for a store, sold as work: we look at what your store actually sends a search engine, put right what is wrong on the store's side, and test each fix again. No ranking is promised.

Common questions

Should page 2 of a category be noindexed?

Google's pagination page does not say so. It treats each page of a list as a page of its own, with its own address and its own canonical link. The noindex it mentions is for sorted and filtered copies of a list.

Should page 2's canonical link point to page 1?

No. Google's pagination page says not to use the first page of a sequence as the canonical page, and to give each page its own canonical URL.

Do I need rel="next" and rel="prev" links?

Not for Google, which says it no longer uses them. Its page adds that other search engines may. WordPress and WooCommerce print neither on a category page.

Does removing product-category from the URL help SEO?

Google's documentation gives no reason to think so. It says it does not generally read a site's structure from its URLs, and the descriptive word, the category's own name, stays either way. Removing the base needs a plugin, and WooCommerce advises against it.

Why is my category missing from the sitemap?

WordPress's sitemap lists only categories that hold at least one product, so an empty one is left out. If the whole file wp-sitemap-taxonomies-product_cat-1.xml is missing, see the WordPress sitemap: an SEO plugin may have replaced it with its own.

More on this subject

SEO audit, done for you

SEO audit is $249. A written audit, each finding with its source, and up to 2 hours of fixes done and tested again. It starts with a free diagnosis.