
🛠 Як додати заголовки 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 дають помітний приріст швидкості, а швидкість — це і користувацький досвід, і позиції в пошуку.



