Atualizado em 19/06/2026
O WooCommerce permite que você substitua qualquer arquivo de template da loja por uma versão sua, copiando-o para o tema. É um recurso oficial e legítimo — mas também a fonte número um de lojas que quebram em atualizações. O motivo é simples: ao copiar um template, você fotografa o markup daquela versão e assume a responsabilidade de mantê-lo. Este guia mostra quando sobrescrever, como fazer com segurança e — igualmente importante — quando não fazer, porque um hook resolveria melhor.
Como o WooCommerce monta as páginas
Antes de mexer em template, é preciso entender de onde vem o HTML. Os templates do WooCommerce ficam em wp-content/plugins/woocommerce/templates/ — arquivos como single-product.php, content-single-product.php, cart/cart.php, checkout/form-checkout.php. Mas eles quase não contêm markup fixo: a montagem real acontece por hooks. Cada template dispara do_action() em vários pontos, e o próprio WooCommerce se pendura nesses pontos para imprimir o título, o preço, o botão de comprar e o resto. Essa arquitetura é justamente o que torna a maioria das customizações possível sem tocar em template algum — assunto que detalho em hooks do WooCommerce.
Quando uma página de loja é requisitada, o WooCommerce localiza o template a ser usado por meio de duas funções centrais: wc_get_template() e wc_get_template_part(). Por baixo delas, o caminho é resolvido com locate_template() (a mesma função que o tema usa) numa ordem de prioridade bem definida: primeiro o tema, só depois o plugin. É exatamente essa ordem que permite o override.
A ordem de busca: por que o tema "vence" o plugin
Ao precisar de, digamos, single-product/title.php, o WooCommerce procura nesta sequência e usa o primeiro que encontrar:
wp-content/themes/SEU-CHILD-THEME/woocommerce/single-product/title.phpwp-content/themes/TEMA-PAI/woocommerce/single-product/title.phpwp-content/plugins/woocommerce/templates/single-product/title.php(o original, fallback)
O nome da pasta dentro do tema — woocommerce/ — não é arbitrário: ele vem do filtro woocommerce_template_path, cujo valor padrão é justamente woocommerce/. Em outras palavras, basta criar essa subpasta no seu tema e replicar o caminho relativo do arquivo que você quer substituir. A partir daí, a sua cópia passa a ser servida no lugar da do plugin, sem que você precise registrar nada.
Esse mecanismo é o irmão WooCommerce do get_template_part() do WordPress: ambos resolvem qual arquivo PHP incluir com base na hierarquia de temas. A diferença é que o WooCommerce adiciona a camada do plugin como último fallback, garantindo que a loja funcione mesmo sem nenhum override no tema.
Hook primeiro, override só quando inevitável
Esta é a decisão mais importante do artigo, então vale repetir: sobrescrever template é o último recurso, não o primeiro. A ordem de preferência ao customizar deve ser:
- Hook (action/filter). Se você quer adicionar, remover ou reposicionar um elemento, faça via
add_action()/remove_action()/add_filter(). Não copia arquivo nenhum, não congela markup, sobrevive às atualizações. É a API pública e estável da loja. - Override. Só quando você precisa mudar o markup interno de um bloco — a marcação que fica entre os hooks e que nenhum action consegue alterar. Aí sim você copia o template para o tema.
Um exemplo torna a diferença concreta. Suponha que você queira tirar os metadados (SKU, categorias) da página de produto. A tentação do iniciante é abrir content-single-product.php, copiar para o tema e apagar a linha. Mas o jeito correto é remover o hook que imprime aqueles metadados:
<?php
/**
* Remove os metadados do produto (SKU, categorias, tags) SEM override.
* Roda dentro de um plugin próprio ou no functions.php do child theme.
*/
add_action( 'init', function () {
// O WooCommerce adiciona os metadados neste hook, nesta prioridade.
remove_action(
'woocommerce_single_product_summary',
'woocommerce_template_single_meta',
40
);
} );
Repare em dois detalhes que decidem se isso funciona: o nome exato do callback (woocommerce_template_single_meta) e a prioridade exata (40). Se a prioridade não bater com a do registro original, o remove_action() falha silenciosamente — um clássico de quem está começando com actions e filters. Você descobre esses valores abrindo o próprio template do WooCommerce e lendo onde o conteúdo padrão é adicionado (normalmente em includes/wc-template-hooks.php).
E se você quiser trocar aquele bloco por um seu? Remova o hook padrão e adicione o seu no mesmo lugar — ainda sem override:
<?php
add_action( 'init', function () {
// 1) Tira o resumo (excerpt) padrão do produto.
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_excerpt', 20 );
// 2) Coloca o seu, na MESMA prioridade, para manter a posição.
add_action( 'woocommerce_single_product_summary', 'dw_resumo_custom', 20 );
} );
function dw_resumo_custom() {
global $product;
$texto = $product->get_short_description();
if ( $texto ) {
echo '<div class="dw-resumo">' . wp_kses_post( $texto ) . '</div>';
}
}
Tudo isso evita override. Só quando a mudança é no markup que está dentro de woocommerce_template_single_excerpt() — e que você não controla por hook — é que a balança pende para sobrescrever o template.
A estrutura de pastas do override
Decidido que o override é mesmo necessário, a regra é espelhar o caminho relativo. Veja a correspondência entre o plugin e o tema:
wp-content/
├─ plugins/woocommerce/templates/ ← NUNCA edite aqui (perde na atualização)
│ ├─ single-product/
│ │ ├─ title.php
│ │ └─ price.php
│ ├─ cart/cart.php
│ └─ checkout/form-checkout.php
│
└─ themes/seu-child-theme/woocommerce/ ← coloque suas cópias aqui
├─ single-product/
│ └─ title.php ← este override "vence" o do plugin
└─ cart/
└─ cart.php
Note que você copia apenas os arquivos que vai modificar — não a pasta inteira. Quanto menos overrides, menos cópias para manter sincronizadas a cada atualização do WooCommerce. E observe que tudo está dentro de um child theme: nunca coloque overrides no tema-pai, ou eles somem quando o tema for atualizado.
Mantendo o cabeçalho @version
Todo template do WooCommerce começa com um cabeçalho de comentário que inclui a versão em que aquele arquivo foi visto pela última vez. Ao copiar para o tema, mantenha esse cabeçalho. Exemplo de um override mínimo de single-product/title.php que apenas adiciona uma classe CSS ao título:
<?php
/**
* Single Product title (override no child theme).
*
* Cópia de woocommerce/templates/single-product/title.php
* Mantenha @version igual à do template original do plugin
* para o painel WooCommerce › Status detectar quando ficar defasado.
*
* @package WooCommerce\Templates
* @version 1.6.4
*/
defined( 'ABSPATH' ) || exit; // bloqueia acesso direto ao arquivo
the_title( '<h1 class="product_title entry-title dw-title">', '</h1>' );
Por que isso importa? Em WooCommerce › Status, a seção de templates lista todos os overrides do seu tema e compara o @version de cada cópia com o do arquivo atual do plugin. Quando o WooCommerce atualiza um template (para corrigir um bug, melhorar acessibilidade ou ajustar markup), a sua cópia fica com um número menor e o painel a marca como desatualizada, em vermelho. Esse alerta é o seu gatilho para abrir o template novo do plugin, comparar com a sua versão e reaplicar a sua customização sobre o markup atualizado.
Ignorar o alerta de "template desatualizado" é como desligar o aviso de óleo do carro. Você pode estar servindo markup com bug de XSS já corrigido, layout quebrado em telas novas ou marcação de acessibilidade antiga. Reserve alguns minutos a cada atualização maior do WooCommerce para revisar overrides defasados — é parte do custo de manutenção que o override impõe e o hook não.
A armadilha moderna: Cart e Checkout em blocos
Aqui está o ponto que mais confunde quem aprendeu override "na era clássica". O WooCommerce hoje oferece dois carrinhos e dois checkouts:
- Clássico (shortcodes): as páginas usam
[woocommerce_cart]e[woocommerce_checkout], renderizados em PHP pelos templates emtemplates/cart/etemplates/checkout/. Aqui o override clássico funciona. - Em blocos (Cart/Checkout Blocks): as páginas usam os blocos do editor, renderizados em React/JavaScript no navegador. Esses blocos NÃO leem os templates PHP clássicos. Copiar
checkout/form-checkout.phppara o tema não tem efeito nenhum sobre eles.
Em instalações recentes, os blocos costumam ser o padrão. Então, se você sobrescreveu form-checkout.php e "nada mudou", quase sempre a causa é essa: a loja está no checkout em blocos. Customizar os blocos é um modelo diferente — filtros e slots/fills de JavaScript, extensões registradas via a API de blocos do WooCommerce — e não tem relação com a pasta woocommerce/ do tema.
Como saber qual checkout sua loja usa? Edite a página "Finalizar compra" (Checkout): se você vê o bloco "Finalizar compra", é o checkout em blocos; se vê o shortcode [woocommerce_checkout], é o clássico. Trocar entre eles é possível pelo próprio editor, mas avalie os impactos — extensões antigas podem depender do checkout clássico.
"Quero mudar X": hook ou override?
Use esta tabela como bússola antes de copiar qualquer arquivo. A coluna da direita mostra o caminho recomendado:
| Quero mudar… | Caminho recomendado |
|---|---|
| Adicionar um aviso entre o preço e o botão de comprar | Hook — add_action('woocommerce_single_product_summary', …, 15) |
| Remover o resumo/SKU/abas do produto | Hook — remove_action() com o callback e a prioridade corretos |
| Trocar o texto do botão "Adicionar ao carrinho" | Hook (filter) — woocommerce_product_single_add_to_cart_text |
| Reordenar campos do checkout clássico | Hook (filter) — woocommerce_checkout_fields (ajuste priority) |
| Reestruturar o HTML interno do título do produto (tag, wrappers) | Override — single-product/title.php |
| Mudar a marcação da tabela do carrinho clássico | Override — cart/cart.php (mantenha @version) |
| Customizar o e-mail de pedido (estrutura) | Override — arquivos de templates/emails/ |
| Qualquer coisa no checkout/carrinho em blocos | Nenhum dos dois — API de blocos (JS), não templates PHP |
Forçando o caminho de busca (avançado)
Em casos específicos — um plugin que precisa fornecer seus próprios templates, ou uma organização de pastas fora do padrão — você pode interferir na resolução do template. O filtro woocommerce_locate_template recebe o caminho que o WooCommerce resolveu e permite redirecioná-lo; o filtro woocommerce_template_path muda a subpasta padrão (woocommerce/) que o tema usa:
<?php
/**
* Faz um plugin servir seus próprios templates quando o tema não os tem.
* Usado por extensões; raramente necessário em um projeto de loja comum.
*/
add_filter( 'woocommerce_locate_template', function ( $template, $template_name, $template_path ) {
// Só intervém se o tema NÃO forneceu um override.
$plugin_path = plugin_dir_path( __FILE__ ) . 'woocommerce/';
if ( file_exists( $plugin_path . $template_name ) ) {
// Se o caminho atual ainda aponta para o core, troca pelo do plugin.
if ( strpos( $template, 'plugins/woocommerce/templates/' ) !== false ) {
return $plugin_path . $template_name;
}
}
return $template;
}, 10, 3 );
Trate isso como ferramenta de quem desenvolve extensões, não como atalho do dia a dia. Para a maioria das lojas, a hierarquia padrão (child theme → tema-pai → plugin) já cobre tudo, e mexer nesses filtros adiciona complexidade que cobra seu preço na manutenção.
Boas práticas e armadilhas comuns
- Hook antes de override. Pergunte-se sempre: "dá para fazer com um
add_action/remove_action?" Se sim, não copie arquivo. - Nunca edite a pasta do plugin. Toda mudança em
plugins/woocommerce/evapora na atualização. Sem exceções. - Use child theme. Overrides no tema-pai somem quando ele é atualizado. No child theme, sobrevivem.
- Copie o mínimo. Sobrescreva o arquivo mais específico possível (ex.:
title.php, nãocontent-single-product.phpinteiro). Menos markup congelado, menos manutenção. - Mantenha o
@version. É o radar que avisa quando sua cópia ficou defasada. Revise os alertas em WooCommerce › Status após cada atualização maior. - Mantenha o
defined( 'ABSPATH' ) || exit;no topo do template copiado, para impedir acesso direto ao arquivo. - Escape a saída. Ao imprimir dados no template, use
esc_html(),esc_attr()ewp_kses_post(). Veja segurança no código. - Lembre dos blocos. Se a loja usa Cart/Checkout em blocos, override clássico não funciona — confira antes de gastar tempo copiando arquivos.
Dominar essa decisão — hook primeiro, override só quando inevitável, sempre com @version e dentro de um child theme — é o que diferencia uma customização profissional de uma que vira dívida técnica. Se a sua loja precisa de uma alteração de markup que parece exigir override, ou se há overrides antigos travando uma atualização, veja também os serviços de suporte e manutenção WooCommerce.
Perguntas frequentes
Quando devo sobrescrever um template em vez de usar um hook?
A regra de ouro: primeiro tente um hook. Se você só precisa adicionar, remover ou reposicionar um elemento, um add_action()/remove_action() resolve sem congelar nenhum arquivo. Sobrescrever só se justifica quando você precisa mudar o markup interno de um bloco — reestruturar a marcação que está entre os hooks, algo que nenhum action permite. Mesmo aí, copie o mínimo possível: prefira sobrescrever single-product/title.php em vez de content-single-product.php inteiro.
Onde exatamente colocar o template sobrescrito?
Em wp-content/themes/SEU-TEMA/woocommerce/, espelhando o caminho relativo que o arquivo tem dentro de plugins/woocommerce/templates/. Ou seja, templates/single-product/title.php vira seu-tema/woocommerce/single-product/title.php. O WooCommerce procura no tema (via wc_get_template() / locate_template()) antes de cair no arquivo do plugin, então a sua cópia "vence".
Posso editar os arquivos dentro da pasta do plugin WooCommerce?
Nunca. Qualquer alteração em wp-content/plugins/woocommerce/ é perdida na próxima atualização do plugin (e atualizar é obrigatório por segurança). É exatamente para evitar isso que existe o sistema de override no tema. Editar o plugin é o erro mais caro e mais comum de quem está começando.
Por que manter o cabeçalho @version no template copiado?
Porque é assim que o WooCommerce sabe se a sua cópia ficou defasada. Em WooCommerce › Status, a aba de status lista os overrides do tema e marca em vermelho aqueles cujo @version é menor que o do template original do plugin. Esse alerta é o seu lembrete de revisar a cópia depois de uma atualização — sem ele, você sobrescreve às cegas e pode estar servindo markup antigo com bugs já corrigidos.
Sobrescrevi o template do checkout e nada mudou. Por quê?
Quase certamente a sua loja usa o checkout em blocos (Cart/Checkout Blocks), introduzido no editor de blocos. Esses blocos são renderizados em React/JavaScript e não usam os templates clássicos em PHP (checkout/form-checkout.php etc.). O override clássico só afeta o checkout/carrinho montado pelos shortcodes [woocommerce_checkout] e [woocommerce_cart]. Para customizar os blocos, o caminho é outro (filtros JS, slots/fills, extensões de bloco).
Override de template é compatível com o tema-pai e o child theme?
Sim, e o child theme é o lugar correto. Coloque os overrides em wp-content/themes/seu-child/woocommerce/: assim, quando o tema-pai for atualizado, as suas cópias não se perdem (ao contrário de editar o tema-pai diretamente). O WooCommerce respeita a hierarquia: procura primeiro no child theme, depois no tema-pai, depois no plugin.