Skip to content

Все для WordPress, веб-розробки — і не тільки

🛠 Як додати заголовки Expires у .htaccess: покрокова інструкція

🛠 Як додати заголовки 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.

Помилка Add Expires Headers у звіті GTmetrix

Спосіб 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 &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>

Що тут відбувається. Перший блок <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 у каталозі WordPress

Порядок встановлення:

  • Плагіни → Додати новий, у пошуку наберіть «AEH Speed Optimization»

  • Натисніть Встановити зараз, потім Активувати

  • Перейдіть у Налаштування → AEH Speed Optimization

  • На вкладці Cache Settings позначте типи файлів і виставте терміни зберігання в днях

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