
🛠 Como adicionar cabeçalhos Expires no .htaccess: guia passo a passo
Executou um teste no GTmetrix e lá está, a vermelho: «Add Expires Headers». Uma imagem familiar. O site está em WordPress, o alojamento em Apache, e o teste de velocidade exige que configure a cache do navegador através de um ficheiro .htaccess.
O erro não é crítico, mas é irritante. Sem cabeçalhos Expires, o navegador recarrega imagens, CSS e scripts do servidor a cada visita. Repetidamente. Mesmo que nada tenha mudado. A velocidade cai, os utilizadores esperam, o Google baixa as classificações.
Pode corrigir isto em cinco minutos. Dois métodos: manualmente através de código no.htaccess ou com um plugin em dois cliques. Abaixo, ambos, com código pronto a usar e definições.
💡 Visão geral rápida:
- Compreender como os cabeçalhos Expires e Cache-Control gerem a cache do navegador
- Adicionar código pronto a usar ao.htaccess: copiar, colar, verificar
- Instalar o plugin AEH Speed Optimization num minuto se não quiser mexer em código
- Configurar períodos de cache ideais para imagens, CSS, JS e fontes
Como funcionam os cabeçalhos Expires
Quando um visitante acede a um site, o navegador carrega dezenas de ficheiros: a página HTML, os estilos CSS, JavaScript, fontes, ícones, imagens. Cada ficheiro é um pedido HTTP separado ao servidor. Quanto mais pedidos, maior o tempo de carregamento.
O cabeçalho Expires diz ao navegador: «este ficheiro não muda, guarda-o em cache e não perguntes novamente até à data X.» Nas visitas repetidas, o navegador obtém os ficheiros da cache local em vez de os ir buscar novamente ao servidor. Resultado: dezenas de pedidos a menos e carregamento rápido.
O equivalente moderno é o cabeçalho Cache-Control com a diretiva max-age. Define o tempo de vida da cache em segundos, não uma data específica, e é atualmente considerado o principal. Recomendamos configurar ambos os cabeçalhos em simultâneo: Expires para navegadores antigos e proxies, Cache-Control para tudo o que é moderno. Ambos são escritos no mesmo bloco do.htaccess.

Método 1: código no.htaccess
O caminho mais direto é adicionar regras de cache diretamente ao ficheiro de configuração do Apache. O ficheiro .htaccess fica na raiz do site (no mesmo local que o wp-config.php). Se não o vir, ative a visualização de ficheiros ocultos no seu cliente de FTP ou no gestor de ficheiros do alojamento.
Antes de editar, descarregue uma cópia do ficheiro para o seu computador. Um erro de sintaxe no.htaccess pode fazer o site cair com um erro 500, uma cópia de segurança permite reverter num segundo.
Abra o .htaccess num editor e adicione o seguinte bloco antes de # BEGIN WordPress:
1 # Browser caching: Expires and Cache-Control headers 2 <IfModule mod_expires.c> 3 ExpiresActive On 4 5 # Images 6 ExpiresByType image/jpg "access plus 1 year" 7 ExpiresByType image/jpeg "access plus 1 year" 8 ExpiresByType image/gif "access plus 1 year" 9 ExpiresByType image/png "access plus 1 year" 10 ExpiresByType image/webp "access plus 1 year" 11 ExpiresByType image/avif "access plus 1 year" 12 ExpiresByType image/svg+xml "access plus 1 year" 13 ExpiresByType image/x-icon "access plus 1 year" 14 15 # CSS and JavaScript 16 ExpiresByType text/css "access plus 1 month" 17 ExpiresByType application/javascript "access plus 1 month" 18 19 # Fonts 20 ExpiresByType font/woff2 "access plus 1 year" 21 ExpiresByType font/woff "access plus 1 year" 22 23 # PDF and other documents 24 ExpiresByType application/pdf "access plus 1 month" 25 26 # Default 27 ExpiresDefault "access plus 2 days" 28 </IfModule> 29 30 # Cache-Control headers for modern browsers 31 <IfModule mod_headers.c> 32 <FilesMatch "\.(jpg|jpeg|png|gif|webp|avif|svg|ico|woff2|woff)$"> 33 Header set Cache-Control "max-age=31536000, public" 34 </FilesMatch> 35 <FilesMatch "\.(css|js)$"> 36 Header set Cache-Control "max-age=2592000, public" 37 </FilesMatch> 38 </IfModule>
O que está a acontecer aqui. O primeiro bloco <IfModule mod_expires.c> ativa o módulo Expires e define os períodos de armazenamento para cada tipo de ficheiro. Um ano para imagens e fontes, elas quase nunca mudam. Um mês para CSS e JavaScript, são atualizados periodicamente.
O segundo bloco <IfModule mod_headers.c> adiciona o moderno Cache-Control com os mesmos períodos, mas em segundos: 31536000 = um ano, 2592000 = um mês.
Importante: os módulos mod_expires e mod_headers têm de estar ativos no servidor. Na maioria dos alojamentos Apache estão ativos por defeito: o suporte ativa-os durante a configuração inicial. Se a cache não funcionar depois de guardar, escreva ao suporte do alojamento: «ative o mod_expires e o mod_headers.»
Depois de colar, guarde o ficheiro e volte a enviá-lo para a raiz do site. Abra o site num navegador, vá a DevTools (F12) → Rede → atualize a página. Clique em qualquer ficheiro CSS ou JS, no separador Cabeçalhos deverá ver Expires e Cache-Control com valores diferentes de zero.
Execute o GTmetrix novamente, o erro deverá ter desaparecido.
Método 2: plugin AEH Speed Optimization
Se não quiser mexer manualmente no.htaccess, existe um plugin. Costumava chamar-se simplesmente Add Expires Headers, hoje evoluiu para AEH Speed Optimization. Além dos cabeçalhos de cache, pode fazer minificação de CSS, lazy loading de imagens e compressão.

Passos de instalação:
Plugins → Adicionar Novo, na pesquisa escreva "AEH Speed Optimization"
Clique em Instalar Agora, depois em Ativar
Vá a Configurações → AEH Speed Optimization
No separador Cache Settings, marque os tipos de ficheiro e defina os períodos de armazenamento em dias

- Clique em Submeter
O plugin escreverá as regras no.htaccess por si, não precisa de escrever uma única linha de código. Para a maioria dos sites, a versão gratuita é suficiente. A versão Pro adiciona compressão Gzip, cache de recursos externos (fontes Google, scripts CDN) e tipos de ficheiro personalizados.

🔗 AEH Speed Optimization no WordPress.org
Se já tem um plugin de cache como o W3 Total Cache ou o WP Rocket, não precisa de um plugin Expires separado. Qualquer plugin de cache sério consegue adicionar cabeçalhos Expires e Cache-Control ao.htaccess automaticamente. Vá às configurações do seu plugin e verifique se o separador Browser Cache está ativo.
Que tempo de cache definir
Não há uma resposta universal, o período depende da frequência com que altera um tipo específico de ficheiro.

Tipo de ficheiro | Período recomendado | Porquê |
|---|---|---|
Imagens (jpg, png, webp, avif, gif, svg) | 1 ano | Mudam raramente, pesam muito, máximo benefício da cache |
Ícones e favicon | 1 ano | Não mudam durante anos |
Fontes (woff2, woff) | 1 ano | Carregadas uma vez e não são atualizadas |
Estilos CSS | 1 mês | Edita de vez em quando; ao redesenhar, limpe a cache |
JavaScript | 1 mês | A mesma lógica do CSS |
PDF e documentos | 1 mês | Descarregados raramente, mas podem ser atualizados |
Regra geral: quanto mais estável for o ficheiro, maior o período. Para imagens, um ano é o padrão. Para CSS e JS, um mês é um compromisso razoável entre velocidade e atualidade.
Se estiver a desenvolver ativamente o site e os estilos mudarem todas as semanas, defina o CSS para uma semana, não um mês. Quando terminar as edições, volte a um mês.
⁉️🤔 Perguntas frequentes
Adicionei código ao.htaccess, mas o GTmetrix ainda mostra o erro. Porquê?
O motivo mais comum é que os módulos
mod_expiresoumod_headersnão estão ativos no servidor. Escreva ao suporte do alojamento a pedir a ativação de ambos os módulos. Segundo motivo: inseriu o código depois de# BEGIN WordPress, e não antes. O WordPress substitui tudo o que vem depois do seu marcador. Terceiro, um plugin de cache (W3 Total Cache, WP Rocket) já gere o.htaccess e substituiu as suas regras pelas dele. Nesse caso, configure o Browser Cache dentro do próprio plugin, não manualmente.
Qual é a diferença entre Expires e Cache-Control?
O
Expiresdefine uma data e hora específicas («válido até 15 de junho de 2027»). OCache-Controlcom a diretivamax-agedefine a duração em segundos a partir do momento do pedido («válido por 31536000 segundos»). OCache-Controlé mais flexível e tem prioridade: se ambos estiverem definidos, o navegador segue oCache-Control. Recomendamos escrever ambos para máxima compatibilidade com clientes antigos e novos.
O site está em Nginx, o.htaccess não funciona. O que fazer?
O ficheiro
.htaccessé configuração do Apache. O Nginx ignora-o. No Nginx, as regras de cache são adicionadas à secçãoserverdo ficheiro de configuração do site com a diretivaexpires. Se tiver Nginx (alojamentos como Kinsta, Cloudways), use o plugin AEH Speed Optimization: funciona em qualquer servidor web porque gere os cabeçalhos através de PHP, não através da configuração do servidor.
Preciso de configurar o Expires se já estiver a usar uma CDN?
Sim. Uma CDN (Cloudflare, BunnyCDN) armazena conteúdo em cache nos seus servidores em todo o mundo, mas a cache do navegador é uma camada separada. Cabeçalhos
ExpireseCache-Controlbem configurados reduzem os pedidos até à CDN: o navegador nem sequer vai à rede buscar um ficheiro se a sua cópia local ainda estiver atualizada. Duas camadas de cache, CDN + navegador, trabalham em conjunto, não se substituem.
O plugin AEH Speed Optimization entra em conflito com o meu plugin de cache?
Pode entrar se ambos tentarem escrever regras no.htaccess. Antes de instalar o AEH Speed Optimization, desative o Browser Cache no seu plugin de cache principal ou, em alternativa, mantenha um único plugin que faça a gestão da cache de páginas e da cache do navegador. O WP Rocket e o W3 Total Cache fazem tudo de raiz, não é necessário um plugin Expires separado com eles.
Deve configurar o Expires manualmente ou um plugin é suficiente?
Se trabalha com FTP com confiança e não tem medo de um editor de código, a configuração manual através do.htaccess dá controlo total e não adiciona um plugin extra ao admin. O código acima: copiar, colar e o assunto fica resolvido.
Para todos os outros, o plugin AEH Speed Optimization resolve a tarefa sem risco de um erro de digitação na configuração. Além disso, fornece minificação e lazy loading, que também aceleram o site.
O principal é não deixar o erro do GTmetrix como está. Cinco minutos para configurar cabeçalhos Expires proporcionam um aumento de velocidade notável, e velocidade é tanto experiência do utilizador como classificações de pesquisa.



