Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

🛠 Come aggiungere le intestazioni Expires in .htaccess: guida passo passo

🛠 Come aggiungere le intestazioni Expires in .htaccess: guida passo passo

Hai eseguito un test su GTmetrix ed eccolo lì, in rosso: «Add Expires Headers». Una scena familiare. Il sito è su WordPress, hosting su Apache, e lo speed test richiede di configurare la cache del browser tramite .htaccess.

L'errore non è critico, ma è fastidioso. Senza gli header Expires, il browser ricarica immagini, CSS e script dal server a ogni visita. Ripetutamente. Anche se non è cambiato nulla. La velocità cala, gli utenti aspettano, Google abbassa il posizionamento.

Puoi risolvere in cinque minuti. Due metodi: manualmente tramite codice in.htaccess o con un plugin in due clic. Di seguito, entrambi, con codice pronto e impostazioni.

💡 Panoramica rapida:

  • Capire come gli header Expires e Cache-Control gestiscono la cache del browser
  • Aggiungere codice pronto in.htaccess: copia, incolla, verifica
  • Installare il plugin AEH Speed Optimization in un minuto se non vuoi toccare codice
  • Configurare periodi di caching ottimali per immagini, CSS, JS e font

Come funzionano gli header Expires

Quando un visitatore arriva su un sito, il browser carica decine di file: la pagina HTML, i fogli di stile CSS, JavaScript, font, icone, immagini. Ogni file è una richiesta HTTP separata al server. Più richieste, più lungo è il tempo di caricamento.

L'header Expires dice al browser: «questo file non cambia, salvalo in cache e non richiederlo più fino a una certa data». Alle visite successive, il browser preleva i file dalla cache locale invece di recuperarli di nuovo dal server. Risultato: decine di richieste in meno e caricamento veloce.

L'equivalente moderno è l'header Cache-Control con la direttiva max-age. Imposta la durata della cache in secondi, non una data specifica, ed è oggi considerato primario. Consigliamo di configurare entrambi gli header simultaneamente: Expires per vecchi browser e proxy, Cache-Control per tutto ciò che è moderno. Entrambi si scrivono nello stesso blocco di.htaccess.

Errore Add Expires Headers nel report GTmetrix

Metodo 1: codice in.htaccess

Il percorso più diretto è aggiungere le regole di caching direttamente al file di configurazione di Apache. Il file .htaccess si trova nella root del sito (stessa posizione di wp-config.php). Se non lo vedi, abilita la visualizzazione dei file nascosti nel tuo client FTP o nel file manager dell'hosting.

Prima di modificare, scarica una copia del file sul tuo computer. Un errore di sintassi in.htaccess può mandare in crash il sito con un errore 500, un backup ti permette di tornare indietro in un secondo.

Apri .htaccess in un editor e aggiungi il seguente blocco prima di # 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>

Cosa succede qui. Il primo blocco <IfModule mod_expires.c> attiva il modulo Expires e imposta i periodi di conservazione per ogni tipo di file. Un anno per immagini e font, non cambiano quasi mai. Un mese per CSS e JavaScript, vengono aggiornati periodicamente.

Il secondo blocco <IfModule mod_headers.c> aggiunge il moderno Cache-Control con gli stessi periodi ma in secondi: 31536000 = un anno, 2592000 = un mese.

Importante: i moduli mod_expires e mod_headers devono essere abilitati sul server. Sulla maggior parte degli hosting Apache sono attivi di default: il supporto li abilita durante la configurazione iniziale. Se il caching non funziona dopo il salvataggio, scrivi al supporto hosting: «abilita mod_expires e mod_headers».

Dopo aver incollato, salva il file e caricalo di nuovo nella root del sito. Apri il sito in un browser, vai su DevTools (F12) → Network → aggiorna la pagina. Clicca su qualsiasi file CSS o JS, nella scheda Headers dovresti vedere Expires e Cache-Control con valori diversi da zero.

Esegui di nuovo GTmetrix, l'errore dovrebbe essere sparito.

Metodo 2: plugin AEH Speed Optimization

Se non vuoi mettere mano manualmente a.htaccess, c'è un plugin. Un tempo si chiamava semplicemente Add Expires Headers, oggi è cresciuto in AEH Speed Optimization. Oltre agli header di caching può fare minificazione CSS, lazy loading delle immagini e compressione.

Pagina del plugin AEH Speed Optimization nel catalogo WordPress

Passaggi di installazione:

  • Plugin → Aggiungi nuovo, nella ricerca digita "AEH Speed Optimization"

  • Clicca Installa ora, poi Attiva

  • Vai su Impostazioni → AEH Speed Optimization

  • Nella scheda Cache Settings, seleziona i tipi di file e imposta i periodi di conservazione in giorni

Impostazioni di caching nel plugin AEH Speed Optimization
  • Clicca Invia

Il plugin scriverà le regole in.htaccess da solo, non devi scrivere una sola riga di codice. Per la maggior parte dei siti la versione gratuita è sufficiente. La versione Pro aggiunge compressione Gzip, caching di risorse esterne (Google Fonts, script CDN) e tipi di file personalizzati.

Esempio di impostazione dei periodi di conservazione per gruppi di file

🔗 AEH Speed Optimization su WordPress.org

Se hai già un plugin di caching come W3 Total Cache o WP Rocket, non hai bisogno di un plugin Expires separato. Qualsiasi plugin di cache serio può aggiungere automaticamente gli header Expires e Cache-Control a.htaccess. Vai nelle impostazioni del tuo plugin e verifica che la scheda Browser Cache sia attiva.

Quale tempo di caching impostare

Non esiste una risposta universale, il periodo dipende da quanto spesso modifichi un tipo di file specifico.

Elenco dei tipi di file per la configurazione della cache nel plugin

Tipo di file

Periodo consigliato

Perché

Immagini (jpg, png, webp, avif, gif, svg)

1 anno

Cambiano raramente, pesano molto, massimo beneficio dalla cache

Icone e favicon

1 anno

Non cambiano per anni

Font (woff2, woff)

1 anno

Caricati una volta e non aggiornati

Fogli di stile CSS

1 mese

Li modifichi di tanto in tanto; in caso di redesign, svuota la cache

JavaScript

1 mese

Stessa logica dei CSS

PDF e documenti

1 mese

Scaricati raramente ma possono essere aggiornati

Regola generale: più il file è stabile, più lungo è il periodo. Per le immagini un anno è lo standard. Per CSS e JS un mese è un compromesso ragionevole tra velocità e freschezza.

Se stai sviluppando attivamente il sito e gli stili cambiano ogni settimana, imposta CSS a una settimana, non un mese. Quando finisci le modifiche, torna a un mese.

⁉️🤔 Domande frequenti

Ho aggiunto codice a.htaccess ma GTmetrix mostra ancora l'errore. Perché?

Il motivo più comune è che i moduli mod_expires o mod_headers non sono abilitati sul server. Scrivi al supporto hosting richiedendo di attivare entrambi i moduli. Secondo motivo: hai inserito il codice dopo # BEGIN WordPress, non prima. WordPress sovrascrive tutto ciò che viene dopo il suo marcatore. Terzo, un plugin di caching (W3 Total Cache, WP Rocket) gestisce già.htaccess e ha sovrascritto le tue regole con le sue. In questo caso, configura la Browser Cache all'interno del plugin stesso, non manualmente.

Qual è la differenza tra Expires e Cache-Control?

Expires imposta una data e un'ora specifica («valido fino al 15 giugno 2027»). Cache-Control con la direttiva max-age imposta la durata in secondi dal momento della richiesta («valido per 31536000 secondi»). Cache-Control è più flessibile e ha priorità: se entrambi sono impostati, il browser segue Cache-Control. Consigliamo di scrivere entrambi per la massima compatibilità con client vecchi e nuovi.

Il sito è su Nginx,.htaccess non funziona. Cosa fare?

Il file .htaccess è configurazione Apache. Nginx lo ignora. Per Nginx, le regole di caching si aggiungono alla sezione server del file di configurazione del sito con la direttiva expires. Se hai Nginx (host come Kinsta, Cloudways), usa il plugin AEH Speed Optimization: funziona su qualsiasi web server perché gestisce gli header tramite PHP, non tramite configurazione del server.

Devo configurare Expires se sto già usando una CDN?

Sì. Una CDN (Cloudflare, BunnyCDN) memorizza i contenuti nella cache sui suoi server in tutto il mondo, ma la cache del browser è un livello separato. Header Expires e Cache-Control configurati correttamente riducono le richieste anche verso la CDN: il browser non va affatto in rete per un file se la sua copia locale è ancora fresca. Due livelli di cache, CDN + browser, lavorano insieme, non si sostituiscono a vicenda.

Il plugin AEH Speed Optimization è in conflitto con il mio plugin di cache?

Può esserlo se entrambi provano a scrivere regole in.htaccess. Prima di installare AEH Speed Optimization, disabilita la Browser Cache nel tuo plugin di caching principale, o al contrario, tieni un solo plugin che gestisca sia la cache delle pagine sia la cache del browser. WP Rocket e W3 Total Cache possono fare tutto nativamente, un plugin Expires separato non è necessario con loro.

Conviene configurare Expires manualmente o basta un plugin?

Se lavori con sicurezza con l'FTP e non hai paura di un editor di codice, la configurazione manuale tramite.htaccess dà il pieno controllo e non aggiunge un plugin extra all'amministrazione. Il codice sopra: copia, incolla e la questione è chiusa.

Per tutti gli altri, il plugin AEH Speed Optimization risolve il problema senza il rischio di un errore di battitura nella configurazione. In più offre minificazione e lazy loading, che velocizzano anch'essi il sito.

La cosa principale è non lasciare l'errore di GTmetrix così com'è. Cinque minuti per configurare gli header Expires danno un boost di velocità percepibile, e la velocità è sia esperienza utente sia posizionamento sui motori di ricerca.