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

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

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

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

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

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_expiresomod_headersnon 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?
Expiresimposta una data e un'ora specifica («valido fino al 15 giugno 2027»).Cache-Controlcon la direttivamax-ageimposta 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 segueCache-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 sezioneserverdel file di configurazione del sito con la direttivaexpires. 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
ExpireseCache-Controlconfigurati 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.



