Якщо записи Custom Post Type існують у базі WordPress, але їхні URL повертають 404, причина часто пов’язана не з конфігурацією Apache або Nginx. WordPress зберігає правила маршрутизації у базі даних, і після додавання нового типу записів ці правила можуть залишитися застарілими.
Найчастіше проблему вирішує коректне оновлення rewrite rules. Водночас викликати flush_rewrite_rules() під час кожного запиту не можна: це створює зайві операції з базою даних і може погіршити продуктивність сайту. Нижче — безпечний підхід для плагіна, перевірки після деплою та типові помилки.
Чому Custom Post Type повертає 404
Під час реєстрації Custom Post Type WordPress отримує інформацію про його slug, архів, ієрархію та правила для окремих записів. На основі цих даних формуються rewrite rules — набір правил, за якими WordPress визначає, який запит відповідає конкретному запису або архіву.
Ці правила не перебудовуються повністю на кожному запиті. WordPress зберігає їх у базі, тому після встановлення або оновлення плагіна вони можуть не відповідати поточній реєстрації CPT. У результаті запис є в адміністративній панелі, але URL на кшталт /portfolio/example/ повертає 404.
Скидання rewrite rules змушує WordPress сформувати їх заново. Однак flush_rewrite_rules() не виправляє помилки в самому register_post_type(): якщо CPT зареєстрований із неправильним slug або не реєструється взагалі, після скидання проблема залишиться.
- CPT був доданий після першого запуску плагіна.
- Змінився slug типу записів або налаштування rewrite.
- Плагін оновили через деплой без повторної активації.
- Правила були скинуті до моменту реєстрації CPT.
- У сайту є конфлікт slug із таксономією, сторінкою або іншим типом записів.
Правильна схема для активації плагіна
Найбезпечніше скидати rewrite rules лише під час активації та деактивації плагіна. Під час активації спочатку потрібно зареєструвати Custom Post Type, а вже потім викликати flush_rewrite_rules(). Інакше WordPress ще не знатиме про новий тип записів і не додасть його маршрути до правил.
Приклад базової реалізації:
function my_register_cpt() {
register_post_type('portfolio', [
'label' => 'Портфоліо',
'public' => true,
'has_archive' => true,
'rewrite' => [
'slug' => 'portfolio',
],
'supports' => ['title', 'editor', 'thumbnail'],
'show_in_rest' => true,
]);
}
add_action('init', 'my_register_cpt');
register_activation_hook(__FILE__, function () {
my_register_cpt();
flush_rewrite_rules();
});
register_deactivation_hook(__FILE__, function () {
flush_rewrite_rules();
});
Чому функцію реєстрації викликають двічі
Виклик через add_action('init', ...) потрібен для звичайних запитів сайту. Окремий виклик у callback активації потрібен тому, що activation hook виконується в спеціальному контексті, до стандартного циклу init. Без цього під час flush_rewrite_rules() CPT може бути ще не зареєстрований.
Назва функції та параметри register_post_type() у реальному проєкті можуть відрізнятися, але порядок дій залишається незмінним: спочатку реєстрація, потім скидання правил.
Чого не можна робити
Поширена помилка — викликати flush_rewrite_rules() у функції, підключеній до init, або безпосередньо в шаблоні. У такому випадку скидання відбувається під час кожного завантаження сторінки, а іноді й під час AJAX- або REST-запитів.
Операція змінює або перебудовує правила маршрутизації та працює з базою даних. Для рідкісної події на кшталт активації плагіна це нормально, але для кожного відвідувача — зайве навантаження.
- Не викликайте flush_rewrite_rules() у init.
- Не розміщуйте його у single-шаблонах або functions.php без умовного одноразового запуску.
- Не запускайте його під час кожного збереження запису CPT.
- Не використовуйте flush як спосіб виправити неправильний post type slug.
- Не скидайте правила в REST-обробниках і AJAX-запитах.
Як виправити 404 після деплою без повторної активації
Якщо плагін уже встановлений і його код оновили через Git, CI/CD або файловий менеджер, activation hook повторно не запускається. Тому доданий у новій версії CPT може не з’явитися в актуальних rewrite rules.
У такій ситуації зручно скористатися WP-CLI. Команду потрібно виконати з кореня WordPress або вказати правильний шлях до інсталяції:
wp rewrite flush
Коли потрібен hard flush
Звичайна команда wp rewrite flush оновлює правила WordPress. Якщо потрібно також перевірити взаємодію з конфігурацією вебсервера, WP-CLI підтримує параметр --hard, але його слід використовувати обережно й лише коли серверне оточення та права доступу це дозволяють.
У більшості випадків для 404 у Custom Post Type достатньо звичайного оновлення правил. Якщо після цього URL не працює, проблема може бути в permalink-структурі, конфігурації сервера або коді реєстрації CPT.
wp rewrite flush --hard
Перевірка реєстрації Custom Post Type
Перед діагностикою rewrite rules переконайтеся, що CPT справді реєструється на потрібному запиті. Перевірте, чи виконується add_action('init', ...), чи немає умови, яка вимикає реєстрацію для фронтенду, і чи не виникає PHP-помилка під час завантаження плагіна.
Важливо також перевірити параметри rewrite. Якщо для CPT задано rewrite => false, WordPress не створюватиме стандартні красиві URL. Якщо використовується власний slug, фактична адреса запису може відрізнятися від назви post type.
- Перевірте правильність першого аргументу register_post_type().
- Переконайтеся, що slug не містить помилок і не дублює slug сторінки.
- Перевірте has_archive, якщо потрібна сторінка архіву CPT.
- Переконайтеся, що запис має статус, доступний на фронтенді, наприклад publish.
- Подивіться журнали PHP, якщо код плагіна не завантажується.
wp post-type list
wp rewrite list | grep portfolio
Інші причини 404 після скидання правил
Якщо після коректного flush URL все ще повертає 404, не варто безкінечно повторювати цю команду. Спочатку перевірте, чи відкривається звичайна сторінка WordPress і чи працюють записи інших типів.
Окрему увагу слід приділити конфліктам адрес. Наприклад, сторінка зі slug portfolio може перетинатися з архівом CPT, який використовує той самий slug. Подібні конфлікти здатні давати непередбачувану маршрутизацію.
На сайтах із кешуванням після зміни правил також може знадобитися очищення page cache або кешу reverse proxy. Це не замінює flush rewrite rules, але старий кеш може приховувати результат виправлення.
- Перевірте, чи не зайнятий CPT-slug сторінкою або таксономією.
- Очистіть кеш після оновлення правил, якщо він використовується.
- Переконайтеся, що WordPress працює з правильними siteurl та home.
- Перевірте правила rewrite сервера, якщо 404 виникає для всіх красивих URL.
- Порівняйте результат на URL запису, архіву та таксономії CPT.
Рекомендації для оновлень плагіна
Якщо новий CPT додається під час оновлення плагіна, не варто покладатися лише на повторну активацію. Користувачі зазвичай оновлюють плагін без деактивації, тому activation hook у цьому сценарії не виконається.
Для складніших змін можна зберігати версію rewrite rules у налаштуваннях плагіна та виконувати flush одноразово після виявлення нової версії. Такий механізм потрібно реалізувати обережно: він має спрацьовувати один раз, а не на кожному запиті.
- Для першого встановлення використовуйте register_activation_hook().
- Для видалення маршрутів після деактивації використовуйте register_deactivation_hook().
- Після деплою без активації застосовуйте wp rewrite flush.
- Після зміни slug пам’ятайте про старі URL, редиректи та можливі 404.
- Тестуйте окремий запис, архів і пов’язані таксономії.
Поширені запитання
Чи потрібно скидати rewrite rules після кожного створення запису CPT?
Ні. Створення, редагування або видалення окремого запису не змінює структуру rewrite rules. Скидання потрібне після реєстрації CPT, зміни його slug або інших параметрів маршрутизації.
Чому flush_rewrite_rules() не допоміг виправити 404?
Можливо, CPT не реєструється, має неправильний slug, вимкнений параметр rewrite або конфліктує зі сторінкою чи таксономією. Також причиною можуть бути кеш або помилки конфігурації вебсервера.
Чи достатньо просто деактивувати й активувати плагін?
У багатьох випадках так, якщо activation hook написаний правильно. Під час активації CPT має бути зареєстрований до виклику flush_rewrite_rules(). Для автоматизованого деплою надійніше виконати wp rewrite flush.
Чи можна викликати flush_rewrite_rules() вручну з адміністративної сторінки?
Можна, якщо запуск обмежений одноразовою дією з перевіркою прав і nonce. Але для стандартного плагіна краще використовувати activation hook, механізм міграції версій або WP-CLI.
Чи впливає show_in_rest на URL Custom Post Type?
Ні, цей параметр керує доступністю типу записів у WordPress REST API та редакторі. Він не замінює параметр rewrite і сам по собі не вирішує 404 для фронтенд-URL.
Висновок
404 для Custom Post Type після встановлення або оновлення плагіна часто виникає через застарілі rewrite rules. Правильна послідовність проста: зареєструвати CPT, оновити правила один раз під час активації або виконати wp rewrite flush після деплою.
Не використовуйте flush_rewrite_rules() у звичайному циклі запитів. Якщо після одноразового скидання URL не запрацював, перевіряйте реєстрацію CPT, slug-конфлікти, кеш і серверну конфігурацію — саме ці причини найчастіше залишаються після коректного оновлення правил.