Filtros, atributos e faceted navigation no WooCommerce
Se você abre site:seudominio.com.br inurl:filter_ no Google e vê dezenas de resultados como /loja/?filter_cor=azul&filter_tamanho=m&orderby=price, o problema não é o WooCommerce — é a configuração padrão dele. A faceted navigation nativa (filtros de widget, ordenação, atributos e faixa de preço) gera uma URL nova para cada combinação de parâmetros. Sem controle, o Googlebot passa a rastrear um espaço combinatório que cresce fatorialmente, enquanto suas categorias principais competem com versões filtradas quase idênticas de si mesmas.
Este artigo é um procedimento técnico para colocar as facetas do WooCommerce sob controle: mapear o que está indexado, decidir quais atributos merecem virar landing page, aplicar noindex,follow nas combinações operacionais, e só depois — com desindexação confirmada — bloquear no robots.txt.
Como o WooCommerce gera URLs facetadas (e por que isso vira problema)
O WooCommerce entrega facetação por três mecanismos distintos, cada um com efeito diferente na indexação:
- Widgets de filtro (Filter by Attribute, Filter by Price, Filter by Rating) — geram query strings como
?filter_cor=azul,?min_price=100&max_price=300,?rating_filter=4. Todas apontam para a mesma categoria pai com um subconjunto do listing. - Ordenação padrão — o dropdown "Ordenar por" adiciona
?orderby=price,?orderby=popularity,?orderby=rating,?orderby=date. Mesmo conjunto de produtos, ordem diferente. - Atributos de produto (Products → Attributes) — quando o atributo tem "Enable Archives" ligado, o WooCommerce cria uma taxonomia real (
/pa_marca/nike/,/pa_cor/vermelho/) com URL amigável e página própria. Quando não tem, o atributo só existe como metadado do produto.
O problema não é a existência dos filtros — usuários precisam deles. O problema é que todas essas URLs, por padrão, respondem HTTP 200 e são rastreáveis. Uma categoria com 6 atributos filtráveis × 3 opções cada × 4 ordenações × 10 faixas de preço já é mais de 7.000 combinações a partir de uma única categoria. O Googlebot rasteia; o conteúdo é quase idêntico ao da categoria pai; o resultado é crawl budget consumido em URLs de baixo valor, sinais de ranking diluídos entre a categoria e suas variantes filtradas, e canibalização quando alguma dessas variantes começa a ranquear no lugar da categoria original.
Passo 1 — Mapear o que já está indexado
Antes de configurar qualquer coisa, meça o tamanho do problema. Três fontes, na ordem:
1.1 — Operadores no Google. Rode buscas como:
`` site:seudominio.com.br inurl:filter_ site:seudominio.com.br inurl:orderby site:seudominio.com.br inurl:min_price ``
O número aproximado de resultados por operador mostra quantas URLs paramétricas o Google já tem no índice. Anote os padrões que mais aparecem — normalmente filter_cor, filter_tamanho e orderby=price lideram.
1.2 — Search Console → Páginas → Cobertura. Filtre por padrões de query string (filter_, orderby, min_price, max_price) tanto na aba "Indexadas" quanto em "Rastreadas mas não indexadas". A segunda categoria é a mais reveladora: são URLs que o Googlebot visitou, decidiu não indexar, mas continua revisitando — puro desperdício de crawl.
1.3 — Log do servidor. Filtre acessos do user-agent Googlebot no access.log das últimas 4 semanas e agrupe por padrão de URL. Se mais de 20-30% dos hits do Googlebot estão em URLs com query string de filtro, você tem um problema de crawl budget mensurável, não teórico.
Guarde essa baseline. É contra ela que você vai comparar em 30, 60 e 90 dias.
Passo 2 — Decidir quais atributos viram landing page (e quais são descartáveis)
Esta é a decisão editorial que define todo o resto da configuração. Nenhuma regra técnica funciona se essa lista estiver errada.
Critério para virar landing indexável: o atributo precisa ter intenção de busca comercial mensurável. Perguntas para validar:
- Existe volume de busca para
[categoria] + [valor do atributo]? (ex: "tênis nike", "vestido vermelho", "sofá 3 lugares") - A combinação faz sentido como página de destino de anúncio ou link externo?
- O conjunto de produtos resultante é diferente o suficiente da categoria pai para justificar página própria?
Atributos que passam nesses três testes tipicamente incluem marca, cor (em algumas verticais) e categoria-específica (ex: "material" em móveis, "estilo" em moda). São 3 a 5 no máximo — mais que isso costuma indicar que você está indexando ruído.
Critério para ficar como faceta descartável (noindex): atributos operacionais — tamanho, ordenação, faixa de preço, disponibilidade, avaliação. Usuário precisa filtrar, mas ninguém busca "camisa polo tamanho M R$ 80 a R$ 120 ordenada por popularidade" no Google.
Passo 3 — Comparar taxonomia pública vs custom attribute
O WooCommerce oferece dois modos de criar atributos, e a diferença é decisiva para SEO:
| | Taxonomia pública (Products → Attributes com "Enable Archives") | Custom attribute (product-level, direto no produto) | |---|---|---| | URL gerada | /pa_marca/nike/ — arquivo público | Nenhuma — só existe dentro do produto | | Indexável | Sim, com página, título, meta description próprios | Não | | Aparece em filtros | Sim | Sim | | Uso ideal | Marca, cor estratégica, categoria-específica | Especificações técnicas sem intenção de busca (voltagem, dimensões exatas) |
A regra prática: use taxonomia pública apenas para atributos que passaram no critério do Passo 2. Para os demais, custom attribute basta — o filtro continua funcionando para o usuário via widget, mas não gera archive indexável competindo com a categoria.
Se você já criou taxonomias públicas para tudo (erro comum), volte em cada uma em Products → Attributes → Edit e desmarque "Enable Archives" naquelas sem intenção de busca. Isso já elimina uma camada inteira do problema antes de você tocar em código.
Passo 4 — Injetar noindex,follow nas combinações não estratégicas
Para toda URL que contenha filter_*, orderby, min_price, max_price (ou combinação delas), você quer que o Googlebot leia a página, siga os links internos, mas não indexe. noindex,follow é exatamente isso.
Adicione ao functions.php do tema filho (ou plugin próprio):
```php add_action( 'wp_head', 'os_noindex_facetas_woocommerce', 1 ); function os_noindex_facetas_woocommerce() { if ( ! function_exists( 'is_shop' ) ) return; if ( ! ( is_shop() || is_product_category() || is_product_tag() ) ) return;
$params_faceta = array( 'orderby', 'min_price', 'max_price', 'rating_filter' ); $tem_faceta = false;
foreach ( $_GET as $chave => $_ ) { if ( strpos( $chave, 'filter_' ) === 0 ) { $tem_faceta = true; break; } if ( in_array( $chave, $params_faceta, true ) ) { $tem_faceta = true; break; } }
if ( $tem_faceta ) { echo '<meta name="robots" content="noindex,follow">' . "\n"; } } ```
Três pontos importantes:
followé obrigatório, nãonofollow. Você quer que o link juice flua da página facetada para os produtos individuais listados nela.- Rode antes do Yoast/RankMath. A prioridade
1noadd_actiongarante que o<meta robots>custom apareça antes do plugin de SEO tentar injetar o dele. Se ambos aparecerem, o Google pega o mais restritivo — ok, mas evita conflito visual no source. - Se seu plugin de SEO já cobre isso (Yoast tem opção "Add noindex to URLs with query string parameters" em versões recentes; RankMath tem regra por padrão de URL), use o plugin e pule este snippet. Duas fontes escrevendo
<meta robots>na mesma página é receita para bug futuro.
Passo 5 — Cadastrar taxonomias estratégicas no sitemap e remover URLs parametrizadas
O sitemap XML é o contrário do que muita gente pensa: ele não é lista do que existe no site, é lista do que você quer que seja indexado. Portanto:
- Incluir: arquivos das taxonomias que sobreviveram ao Passo 2 (
/pa_marca/nike/,/pa_marca/adidas/, etc.). No Yoast:Search Appearance → Taxonomies → [atributo] → Show in sitemap: Yes. No RankMath:Sitemap Settings → Taxonomies. - Excluir: qualquer URL com query string. Sitemaps padrão do WooCommerce/Yoast/RankMath já não incluem URLs parametrizadas — se a sua está incluindo, revise o gerador de sitemap ou plugin custom que estiver rodando.
Depois de publicar o sitemap ajustado, reenvie no Search Console (Sitemaps → Adicionar/testar sitemap). Isso acelera o recrawl das URLs corretas.
Passo 6 — Bloqueio de crawl no robots.txt (só depois da desindexação)
Este é o passo em que mais gente erra a ordem. A regra é: você não pode bloquear no robots.txt uma URL que ainda precisa ser rastreada para o Google ler o noindex. Se você bloquear antes, o Google para de visitar, nunca vê a tag, e a URL fica em limbo — pode continuar indexada por meses.
O fluxo correto:
- Passo 4 aplicado (noindex,follow servindo há 30 a 60 dias).
- Search Console → Cobertura confirma que as URLs facetadas migraram para "Excluída por tag noindex".
site:no Google confirma queda no volume de URLs paramétricas indexadas.- Agora sim, adicione ao
robots.txt:
`` User-agent: Disallow: /?filter_ Disallow: /?orderby= Disallow: /?min_price= Disallow: /?max_price= Disallow: /?rating_filter= Disallow: /&filter_ Disallow: /&orderby= ``
Note as duplicações com ? e &. O primeiro parâmetro na URL vem depois de ?; os demais depois de &. Sem cobrir ambos, você deixa metade das combinações passar.
Teste cada padrão no robots.txt Tester do Search Console antes de subir para produção. Um Disallow mal escrito pode bloquear rotas legítimas — ex: Disallow: /*?filter sem underscore bloquearia também ?filterset=xyz de outro plugin.
Passo 7 — Verificar que os sinais não se contradizem
Depois de aplicar Passos 4 a 6, teste 3 tipos de URL no Search Console → Inspeção de URL:
- URL limpa da categoria (
/loja/tenis/): deve retornarIndexação permitida: Sim, semnoindex, e o arquivo deve estar no sitemap. - URL de taxonomia estratégica (
/pa_marca/nike/): mesmo comportamento da categoria — indexável, no sitemap. - URL facetada descartável (
/loja/tenis/?filter_cor=azul&orderby=price):Indexação permitida: Não, motivonoindex. Se robots.txt já estiver bloqueando, apareceráBloqueada pelo robots.txt— e isso só deve acontecer depois da desindexação confirmada.
Contradições comuns para caçar:
robots.txtbloqueia + página temnoindex→ o Google não lê o noindex, URL pode ficar indexada como "sem descrição". Solução: remover Disallow temporariamente até desindexar.- Página com
noindex,nofollow(em vez denoindex,follow) → link juice bloqueado, produtos internos perdem sinais. Solução: trocar parafollow. - Yoast/RankMath sobrescrevendo o meta robots do snippet custom → fonte duplicada. Solução: escolher uma fonte só.
Passo 8 — Remediar canibalização quando já existe
Se o mapeamento do Passo 1 revelou URLs facetadas específicas ranqueando no lugar de categorias (ex: /loja/?filter_cor=preto aparecendo para "vestido preto" antes da categoria /loja/vestidos/), há duas remediações — e você escolhe uma, nunca as duas:
Opção A — Redirect 301 da URL facetada para a categoria pai. Serve quando a URL facetada não tem intenção comercial própria e não deveria existir nem como filtro isolado (ex: combinações raras que só ganharam autoridade por acaso). Adicione a regra no .htaccess ou via plugin como Redirection.
Opção B — Manter canonical + noindex e aguardar reprocessamento. Serve quando o filtro tem uso pelo usuário e você não quer quebrar bookmarks/links externos. É o caminho já configurado nos Passos 4 e 5 — só requer paciência (30 a 90 dias para reprocessar).
Nunca aplique 301 e canonical simultaneamente. O 301 é um sinal de código HTTP que anula qualquer canonical na resposta (a URL já não retorna 200, e sim 301 → o Google segue o Location e ignora o resto). Se você configurar os dois, o comportamento é imprevisível dependendo de como o servidor entrega a resposta.
Passo 9 — Monitoramento contínuo
Facetação não é configurar-e-esquecer. WooCommerce recebe atributos novos, plugins adicionam parâmetros próprios, temas mudam a UI de filtros. Coloque no calendário:
- Semanal (5 minutos): filtrar log de servidor por
Googlebot+ query string de filtro. Se hits em URLs paramétricas voltarem a crescer, algum plugin novo está gerando padrão não coberto pelo robots.txt. - Mensal (15 minutos): rodar de novo
site:dominio.com.br inurl:filter_e comparar com a baseline do Passo 1. A curva deve ser decrescente nos primeiros 60-90 dias, depois estável. - Trimestral (30 minutos): revisar a lista de atributos com "Enable Archives" ativo. Verticais mudam — o que era atributo estratégico há 6 meses pode ter perdido volume; o que era operacional pode ter ganhado.
Resumo operacional
A ordem importa mais que o conteúdo de cada passo:
- Mapear o dano (Google
site:, Search Console, log). - Decidir os 3-5 atributos estratégicos.
- Ativar "Enable Archives" só nesses; desligar nos demais.
noindex,followem toda URL comfilter_*,orderby,min_price,max_price.- Sitemap com taxonomias estratégicas; sem URLs parametrizadas.
- Aguardar 30-60 dias e confirmar desindexação.
- Só então
Disallowno robots.txt. - Verificar consistência dos três sinais (canonical, meta robots, robots.txt).
- Remediar canibalização caso a caso (301 OU canonical+noindex, nunca ambos).
- Monitorar semanal/mensal/trimestral.
Pular a espera entre 4 e 7 é o erro mais comum e o mais custoso — desfazer um Disallow prematuro pode levar mais 60 dias para o Google reprocessar. Faça na ordem.