Skip to content

Tudo para WordPress, desenvolvimento web — e não só

🛠 Como adicionar cabeçalhos Expires no .htaccess: guia passo a passo

🛠 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.

Erro de cabeçalhos de expiração no relatório do GTmetrix

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 &lt;FilesMatch &quot;\.(jpg|jpeg|png|gif|webp|avif|svg|ico|woff2|woff)$&quot;&gt;
33 Header set Cache-Control "max-age=31536000, public"
34 </FilesMatch>
35 &lt;FilesMatch &quot;\.(css|js)$&quot;&gt;
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.

Página do plugin AEH Speed Optimization no catálogo do WordPress

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

Configurações de cache no plugin AEH Speed Optimization
  • 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.

Exemplo de definição de períodos de armazenamento para grupos de ficheiros

🔗 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.

Lista de tipos de ficheiro para configuração de cache no plugin

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_expires ou mod_headers nã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 Expires define uma data e hora específicas («válido até 15 de junho de 2027»). O Cache-Control com a diretiva max-age define a duração em segundos a partir do momento do pedido («válido por 31536000 segundos»). O Cache-Control é mais flexível e tem prioridade: se ambos estiverem definidos, o navegador segue o Cache-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ção server do ficheiro de configuração do site com a diretiva expires. 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 Expires e Cache-Control bem 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.