Turning WooCommerce Filters Into Landing Pages Google Actually Indexes
Faceted navigation is an SEO minefield. Here's how I turned a store's product filters into rankable landing pages — dynamic titles from the URL, and strict index control.
- WooCommerce
- Technical SEO
- PHP
Faceted navigation is a trap and an opportunity
Every WooCommerce store with attribute filters — size, color, brand, season — is sitting on the same double-edged sword. Those filters generate URLs, and URLs are pages, and pages can rank. A tire store’s “winter / 205 / 55 / R16” filter combo is exactly what a buyer types into Google. That’s the opportunity.
The trap: filters combine. Four attributes with ten options each is ten thousand URLs, most of them near-duplicates of each other, all competing for the same rankings and burning your crawl budget. Left unmanaged, faceted navigation doesn’t help your SEO — it dilutes it into oblivion.
The whole game is: make the valuable combinations into real landing pages, and stop the rest from existing in the index. Here’s how I did it on a real store.
1. Build the title and meta from the filter state
A filtered URL should never show the generic shop <title>. Read the active filters
and construct a snippet that matches the search intent:
function custom_title( $title ) {
$uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
if ( '/shyny/' !== $uri ) return $title;
$parts = [];
if ( ! empty($_GET['filter_vyrobnyk']) ) {
$parts[] = sanitize_text_field($_GET['filter_vyrobnyk']); // brand
}
if ( ! empty($_GET['filter_sezon']) ) {
$map = ['zymovi' => 'зимові', 'litni' => 'літні', 'vsesezonka' => 'всесезонні'];
$parts[] = $map[ $_GET['filter_sezon'] ] ?? ''; // translate the slug
}
// ...width, profile, diameter...
$title['title'] = $parts
? 'Шини ' . implode(' ', $parts) . ' — купити в Україні'
: 'Шини — купити в Україні';
return $title;
}
add_filter( 'document_title_parts', 'custom_title' );
Two details matter more than they look. Translate the slugs — zymovi is a URL
token, «зимові» is what a human searches. And keep a sensible fallback for the
bare page, so an un-filtered view still has a good title.
2. Give the good combinations pretty URLs
Query strings work but read as junk. A few rewrite_rules_array rules turn them into
clean, hierarchical paths that users and crawlers trust:
add_filter( 'rewrite_rules_array', function( $rules ) {
return [
'shyny/([^/]*?)/page/([0-9]+)/?$' => 'index.php?product_cat=$matches[1]&paged=$matches[2]',
'shyny/([^/]*?)/?$' => 'index.php?product_cat=$matches[1]',
] + $rules;
});
3. Control the index — the part everyone skips
This is where most faceted-SEO attempts fall apart. My rule was blunt and effective: too many filters at once = noindex.
function add_noindex_meta_tag() {
if ( preg_match_all('/filter_/', $_SERVER['REQUEST_URI']) >= 4 ) {
echo '<meta name="robots" content="noindex, nofollow" />' . "\n";
}
}
add_action('wp_head', 'add_noindex_meta_tag');
Three-or-fewer-filter combinations are the sweet spot — specific enough to match a real search, broad enough to have inventory and not be a duplicate of ten neighbors. Beyond that, they get blocked.
The inverse also matters: for the specific landing pages I did want ranking, I
stripped any stray noindex an interacting plugin had added, at the output-buffer
level, so nothing accidentally deindexed a page I’d chosen to promote:
add_action('template_redirect', function () {
if ( strpos($_SERVER['REQUEST_URI'], '/ru/shynu/') !== false ) {
ob_start(function ($html) {
return preg_replace(
'/<meta[^>]+name=["\']robots["\'][^>]*content=["\'][^"\']*noindex[^"\']*["\'][^>]*>/i',
'', $html
);
});
}
});
Output buffering to rewrite the final HTML is a heavy hammer — but when three plugins
(WooCommerce, the filter plugin, the SEO plugin) each think they own the <head>, it’s
sometimes the only place you can get the last word.
4. Don’t forget pagination and canonicals
Paginated category pages are duplicate-title machines. Append the page number to the
title and meta, emit rel="prev"/rel="next", and canonicalize the plain shop page
to itself so filtered variants don’t split its signals. Unglamorous, necessary.
The principle
Faceted-navigation SEO isn’t one feature — it’s a policy: which of the pages my site can generate are allowed to exist in Google’s index, and what does each one say about itself? WooCommerce and its plugins generate the pages; they don’t answer that question. The answer is custom code sitting in the seam between them — a few hundred lines that decide, per URL, “index this and call it winter tires 205/55 R16” or “block this, it’s the ten-thousandth near-duplicate.” Get that policy right and your filters stop being a liability and start being your entire long-tail strategy.