
🛠 Как добавить заголовки Expires в .htaccess: пошаговая инструкция
Вы запустили тест в GTmetrix, а там красным: «Add Expires Headers». Знакомая картина. Сайт на WordPress, хостинг на Apache, и тест скорости требует настроить кеширование браузера через какой-то.htaccess.
Ошибка не критичная, но неприятная. Без заголовков Expires браузер при каждом визите заново грузит картинки, CSS и скрипты с сервера. Повторно. Даже если ничего не менялось. Скорость падает, пользователь ждёт, Google снижает позиции.
Исправить это можно за пять минут. Два способа: руками через код в.htaccess или плагином в два клика. Ниже, оба, с готовым кодом и настройками.
💡 Быстрый обзор:
- Разберитесь, как заголовки Expires и Cache-Control управляют кешем браузера
- Добавьте готовый код в.htaccess: скопируйте, вставьте, проверьте
- Установите плагин AEH Speed Optimization за минуту, если не хотите трогать код
- Настройте оптимальные сроки кеширования для изображений, CSS, JS и шрифтов
Как работают заголовки Expires
Когда посетитель заходит на сайт, браузер загружает десятки файлов: HTML-страницу, CSS-стили, JavaScript, шрифты, иконки, картинки. Каждый файл, это отдельный HTTP-запрос к серверу. Чем больше запросов, тем дольше загрузка.
Заголовок Expires говорит браузеру: «этот файл не меняется, сохрани его в кеш и не переспрашивай до такой-то даты». При повторном визите браузер достаёт файлы из локального кеша, а не тянет с сервера заново. Итог, минус десятки запросов и быстрая загрузка.
Современный аналог, заголовок Cache-Control с директивой max-age. Он задаёт время жизни кеша в секундах, а не конкретную дату, и сегодня считается основным. Мы советуем настраивать оба заголовка одновременно: Expires для старых браузеров и прокси, Cache-Control для всего современного. Оба прописываются в одном блоке.htaccess.

Способ 1: код в.htaccess
Самый прямой путь, добавить правила кеширования прямо в конфигурационный файл Apache. Файл .htaccess лежит в корне сайта (там же, где wp-config.php). Если вы его не видите, включите отображение скрытых файлов в FTP-клиенте или файловом менеджере хостинга.
Перед правкой обязательно скачайте копию файла на компьютер. Ошибка в синтаксисе.htaccess может положить сайт с ошибкой 500, бэкап позволит откатиться за секунду.
Откройте .htaccess в редакторе и добавьте следующий блок перед # BEGIN WordPress:
1 # Кеширование браузера: заголовки Expires и Cache-Control 2 <IfModule mod_expires.c> 3 ExpiresActive On 4 5 # Изображения 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 и JavaScript 16 ExpiresByType text/css "access plus 1 month" 17 ExpiresByType application/javascript "access plus 1 month" 18 19 # Шрифты 20 ExpiresByType font/woff2 "access plus 1 year" 21 ExpiresByType font/woff "access plus 1 year" 22 23 # PDF и другие документы 24 ExpiresByType application/pdf "access plus 1 month" 25 26 # По умолчанию 27 ExpiresDefault "access plus 2 days" 28 </IfModule> 29 30 # Заголовки Cache-Control для современных браузеров 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>
Что здесь происходит. Первый блок <IfModule mod_expires.c> активирует модуль Expires и задаёт сроки хранения для каждого типа файлов. Год для изображений и шрифтов, они почти не меняются. Месяц для CSS и JavaScript, их периодически обновляют.
Второй блок <IfModule mod_headers.c> добавляет современный Cache-Control с теми же сроками, но в секундах: 31536000 = год, 2592000 = месяц.
Важно: модули mod_expires и mod_headers должны быть включены на сервере. На большинстве хостингов Apache они активны по умолчанию: поддержка включает их при первоначальной настройке. Если после сохранения кеширование не заработало, напишите в поддержку хостинга: «включите mod_expires и mod_headers».
После вставки сохраните файл и загрузите обратно в корень сайта. Откройте сайт в браузере, зайдите в DevTools (F12) → Network → обновите страницу. Кликните на любой CSS- или JS-файл, во вкладке Headers должны появиться Expires и Cache-Control с ненулевыми значениями.
Повторно запустите GTmetrix, ошибка должна уйти.
Способ 2: плагин AEH Speed Optimization
Если не хотите лезть в.htaccess руками, есть плагин. Когда-то он назывался просто Add Expires Headers, сегодня вырос в AEH Speed Optimization. Помимо заголовков кеширования он умеет минификацию CSS, ленивую загрузку изображений и сжатие.

Порядок установки:
Плагины → Добавить новый, в поиске наберите «AEH Speed Optimization»
Нажмите Установить сейчас, затем Активировать
Перейдите в Настройки → AEH Speed Optimization
На вкладке Cache Settings отметьте типы файлов и выставьте сроки хранения в днях

- Нажмите Submit
Плагин сам пропишет правила в.htaccess, ни одной строчки кода писать не придётся. Для большинства сайтов бесплатной версии хватает. Pro-версия добавляет Gzip-сжатие, кеширование внешних ресурсов (шрифты Google, скрипты CDN) и пользовательские типы файлов.

🔗 AEH Speed Optimization на WordPress.org
Если у вас уже стоит плагин кеширования вроде W3 Total Cache или WP Rocket, отдельный плагин для Expires не нужен. Любой серьёзный кеш-плагин умеет добавлять заголовки Expires и Cache-Control в.htaccess автоматически. Зайдите в настройки своего плагина и проверьте, что вкладка Browser Cache активна.
Какое время кеширования выставить
Универсального ответа нет, срок зависит от того, как часто вы меняете конкретный тип файлов.

Тип файлов | Рекомендуемый срок | Почему |
|---|---|---|
Изображения (jpg, png, webp, avif, gif, svg) | 1 год | Меняются редко, весят много - максимальный эффект от кеша |
Иконки и favicon | 1 год | Не меняются годами |
Шрифты (woff2, woff) | 1 год | Подключаются один раз и не обновляются |
CSS-стили | 1 месяц | Правите время от времени; при смене дизайна - сбросьте кеш |
JavaScript | 1 месяц | Та же логика, что для CSS |
PDF и документы | 1 месяц | Скачиваются редко, но могут обновляться |
Общее правило: чем стабильнее файл, тем дольше срок. Для изображений год, стандарт. Для CSS и JS месяц, разумный компромисс между скоростью и актуальностью.
Если вы активно дорабатываете сайт и стили меняются каждую неделю, поставьте CSS на неделю, а не на месяц. Закончили правки, верните месяц.
⁉️🤔 Частые вопросы
Добавил код в.htaccess, но GTmetrix всё равно показывает ошибку. Почему?
Самая частая причина, модули
mod_expiresилиmod_headersне включены на сервере. Напишите в поддержку хостинга с просьбой активировать оба модуля. Вторая причина, вы вставили код после# BEGIN WordPress, а не до него. WordPress перезаписывает всё, что идёт после своего маркера. Третья, плагин кеширования (W3 Total Cache, WP Rocket) уже управляет.htaccess и перезаписал ваши правила своими. В этом случае настройте Browser Cache внутри самого плагина, а не вручную.
Чем отличается Expires от Cache-Control?
Expiresзадаёт конкретную дату и время («действителен до 15 июня 2027 года»).Cache-Controlс директивойmax-ageзадаёт длительность в секундах от момента запроса («действителен 31536000 секунд»).Cache-Controlгибче и имеет приоритет: если заданы оба, браузер слушаетсяCache-Control. Мы советуем прописывать оба, для максимальной совместимости со старыми и новыми клиентами.
Сайт на Nginx,.htaccess не работает. Что делать?
Файл
.htaccess, это конфигурация Apache. Nginx его игнорирует. Для Nginx правила кеширования добавляются в секциюserverконфигурационного файла сайта директивойexpires. Если у вас Nginx (хостинги вроде Kinsta, Cloudways), используйте плагин AEH Speed Optimization: он работает на любом веб-сервере, так как управляет заголовками через PHP, а не через конфигурацию сервера.
Нужно ли настраивать Expires, если уже используется CDN?
Да. CDN (Cloudflare, BunnyCDN) кеширует контент на своих серверах по всему миру, но браузерный кеш, это отдельный уровень. Правильно настроенные
ExpiresиCache-Controlуменьшают количество запросов даже к CDN: браузер вообще не идёт в сеть за файлом, если его локальная копия ещё свежая. Два уровня кеша, CDN + браузер, работают вместе, а не заменяют друг друга.
Плагин AEH Speed Optimization конфликтует с моим кеш-плагином?
Может, если оба пытаются писать правила в.htaccess. Перед установкой AEH Speed Optimization отключите Browser Cache в вашем основном плагине кеширования, либо наоборот, оставьте один плагин, который управляет и кешем страниц, и браузерным кешем. WP Rocket и W3 Total Cache умеют всё из коробки, отдельный плагин для Expires при них не нужен.
Стоит ли настраивать Expires вручную или хватит плагина?
Если вы уверенно работаете с FTP и не боитесь редактора кода, ручная настройка через.htaccess даёт полный контроль и не добавляет лишний плагин в админку. Код выше, скопируйте, вставьте, и вопрос закрыт.
Для всех остальных плагин AEH Speed Optimization решает задачу без риска опечатки в конфиге. Плюс даёт минификацию и ленивую загрузку, которые тоже ускоряют сайт.
Главное, не оставлять ошибку GTmetrix как есть. Пять минут на настройку заголовков Expires дают заметный прирост скорости, а скорость, это и пользовательский опыт, и позиции в поиске.



