SEO з Ігорем Абрамовським
SEO-кейс: як застарілі вакансії заважали індексації
Як закриті вакансії та дублікати спалюють краулінговий бюджет сайту? Практичний SEO-кейс: оптимізація статусів, налаштування JobPosting та Indexing API.

Вступ. Сайт росте, але користі від нових сторінок усе менше

Уявімо регіональний портал пошуку роботи «Кар'єраРегіон». Він працює в шести областях України, щомісяця отримує тисячі нових вакансій і заробляє на платних розміщеннях роботодавців. У каталозі є вакансії для логістики, виробництва, торгівлі та сервісних компаній.

На перший погляд бізнес має чудову SEO-модель: що більше вакансій, то більше посадкових сторінок, а отже — більше пошукових запитів. Проте уявна команда помічає суперечність. Нові вакансії інколи отримують перший візит Googlebot лише через кілька десятків годин, а старі оголошення місяцями залишаються доступними в пошуку. Людина переходить із Google, натискає «Відгукнутися» й дізнається, що набір завершено.

Мені цікаві саме такі ситуації: проблема виглядає як «Google погано індексує», хоча насправді починається з того, як сайт керує життєвим циклом власних даних.

1. Вихідні дані

На дату умовного аудиту в базі 12 400 URL окремих вакансій. Їх класифікували за статусом, а не просто за відповіддю сервера:

Група URL

Кількість

Що виявили

Актуальні вакансії

2 360

Заявки ще приймають

Закриті вакансії

8 920

Набір завершено, але сторінки переважно відповідають HTTP 200

Дублі або некоректні записи

1 120

Повторні імпорти, помилки джерел, тестові оголошення

Усього

12 400


Це лише склад URL, а не доказ того, що всі 12 400 сторінок індексовані Google. Для цього потрібні окремі дані Search Console, вибіркова перевірка URL та аналіз пошукової видимості.

Бізнес-завдання: збільшити кількість відгуків на актуальні вакансії, зменшити переходи на вже закриті оголошення й прискорити інформування пошукової системи про появу та закриття вакансій.

Обмеження: двоє розробників, один SEO-фахівець, часткова зайнятість аналітика, вісім тижнів на реалізацію першого етапу. Міграцію CMS або повне переписування порталу не плануємо.

2. Перша гіпотеза виявилася помилковою

На старті хтось із команди пропонує очевидне рішення: «Додаймо всі URL у sitemap, поставмо новий lastmod і Google швидше обійде сайт».

Такий план здається дешевим. У змодельованому експерименті розробник формує один XML Sitemap на всі 12 400 адрес і щодня встановлює lastmod на поточну дату, навіть якщо вакансія не змінювалася.

Через два тижні суттєвого прискорення не видно. Це не дивно: sitemap допомагає знаходити сторінки, але не наказує Google негайно сканувати чи індексувати їх. А lastmod має відображати реальну дату значущої зміни URL, а не час генерації файлу.

Висновок першої невдалої гіпотези: штучне оновлення sitemap не виправляє поганий контроль життєвого циклу вакансій.

3. Що показав аудит

3.1. Сервер повертав 200 навіть для закритих вакансій

Наявність HTTP 200 не є помилкою сама по собі: архівна сторінка може бути корисною. Проблема виникала тоді, коли сторінка видавала себе за активну вакансію, хоча роботодавець уже не наймав працівників.

Деякі такі URL досі містили кнопку «Відгукнутися», а база лише після надсилання форми повідомляла про закриття. Для користувача це марна трата часу, а для бізнесу — неякісні заявки.

3.2. Структуровані дані JobPosting не відповідали статусу

На значній частині закритих вакансій залишалася розмітка JobPosting. У частини записів validThrough не було взагалі; в інших термін дії не синхронізувався з рішенням роботодавця закрити набір достроково.

Google вимагає, щоб JobPosting відповідав реальній окремій вакансії, а закрите оголошення не виглядало активним. Якщо вакансія закінчилася, треба своєчасно прибрати оголошення з відповідного досвіду пошуку: наприклад, видалити сторінку (404 або 410), прибрати JobPosting, або вказати минулий validThrough. Недотримання цих вимог може призвести до ручних заходів. Це ризик, а не твердження, що в нашому сценарії санкції вже були.

3.3. Категорії посилалися на старі оголошення

Сторінки «Робота у Вінниці» та «Вакансії комірника» формувалися за датою створення запису, а не за фактичним статусом. У результаті старі оголошення опинялися вище нових, а корисні внутрішні посилання йшли на сторінки без актуальної пропозиції.

3.4. Дублікати виникали через повторні імпорти

Одна й та сама вакансія могла з'явитися під новим ID, якщо джерело змінило формат фіда. Наприклад, /jobs/5281-komirnyk-vinnytsia/ і /jobs/7390-komirnyk-vinnytsia/ показували практично тотожну позицію одного роботодавця, але не мали узгодженої канонічної адреси.

3.5. Не було автоматичного повідомлення про зміни

База даних знала, що вакансія закрилася, а сайт не передавав це в технічний механізм оновлення URL. Для короткоживучих сторінок вакансій Google підтримує спеціальний Indexing API. Його можна використовувати для повідомлень про появу, оновлення або видалення підтримуваних URL. Проте успішна відповідь API означає прийняття повідомлення, а не гарантію індексації.

4. Рішення, яке ми не стали впроваджувати: видалити все старе

Умовний менеджер запропонував за одну ніч видалити 8 920 закритих вакансій і налаштувати переадресацію всіх таких URL на головну сторінку порталу.

Це було б технічно простим, але невдалим підходом. На частину старих URL могли вести зовнішні посилання, окремі записи містили унікальні відомості, а переадресація на нерелевантну головну не допомагає користувачеві знайти аналогічну вакансію. Масові невідповідні редиректи ризикують бути сприйняті як soft 404.

Ми замінили цю пропозицію класифікацією за цінністю та станом URL, а не автоматичним видаленням за віком.

5. Практичний план оптимізації

Крок 1. Створити одне джерело правди про статус вакансії

У базі для кожного запису зберігатимемо job_id, status (active, closed, invalid), published_at, closed_at, updated_at, ідентифікатор роботодавця та зовнішній ID із джерела. Статус розраховується за бізнес-логікою: ручне закриття роботодавцем важливіше за заплановану дату завершення.

Зміна статусу має створювати подію: JOB_CREATED, JOB_UPDATED, JOB_CLOSED або JOB_REMOVED. Тоді SEO-механізми працюватимуть не на здогадках, а на тих самих даних, що й бізнес.

Крок 2. Розділити URL на чотири сценарії

Стан

HTTP / індексація

Дії

A. Вакансія активна

200, потенційно indexable

Реальна форма відгуку, власний canonical, коректний JobPosting, sitemap

B. Закрита, без цінності архіву

404 або 410

Прибрати з навігації та sitemap; після фактичного видалення повідомити API

C. Закрита, але має самостійну архівну цінність

200 без активної вакансії

Явно написати «Набір завершено», прибрати кнопку відгуку та JobPosting, дати релевантні альтернативи; індексацію вирішувати окремо

D. Справжній дубль

Один пріоритетний URL

Канонікалізація або 301 на еквівалентну сторінку, якщо це обґрунтовано; виправлення імпорту

Важливо: залишати закриту вакансію в архіві лише «заради ваги URL» — не стратегія. Архів має давати користувачеві унікальну інформацію. Не варто залишати фіктивно активний JobPosting на архівній сторінці.

Крок 3. Виправити JobPosting на активних сторінках

Приклад для умовної дійсно відкритої вакансії (дати й організація демонстраційні):

<link rel="canonical" href="https://example.org/jobs/5281-komirnyk-vinnytsia/">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "JobPosting",
"title": "Комірник",
"description": "<p>Робота на складі у Вінниці.</p><p>Обов'язки: приймання товару та облік залишків.</p><p>Вимоги: уважність, базова комп'ютерна грамотність.</p><p>Графік: повний робочий день.</p>",
"datePosted": "2026-10-25",
"validThrough": "2026-11-25T23:59:00+02:00",
"employmentType": "FULL_TIME",
"hiringOrganization": {
"@type": "Organization",
"name": "Приклад Логістика",
"sameAs": "https://example.org/employers/pryklad-logistyka/"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"addressLocality": "Вінниця",
"addressRegion": "Вінницька область",
"addressCountry": "UA"
}
}
}
</script>

Самого JSON-LD недостатньо: назва, опис, роботодавець, місце роботи та реальний спосіб подання заявки мають відповідати видимому змісту сторінки. Для цього випадку потрібно також показати робочу кнопку або контакт для подання заявки. Якщо роботодавець закриє вакансію 20 листопада, чекати до validThrough 25 листопада не можна.

Після шаблонних змін перевіряємо Rich Results Test, URL Inspection і вибірку сторінок на мобільному пристрої. Структуровані дані створюють можливість спеціального відображення у Google, але не гарантують його.

Крок 4. Впровадити Indexing API коректно

Для підтримуваних сторінок із JobPosting:

Нова або змістовно оновлена відкрита вакансія → URL_UPDATED.

Сторінку остаточно видалено (404/`410`) або встановлено noindex → URL_DELETED, після перевірки фактичної відповіді сторінки.

Якщо закрита сторінка залишається доступною (200) як архів, не слід надсилати URL_DELETED лише тому, що вакансію закрили. Потрібно оновити HTML і прибрати невідповідний JobPosting; подальший сценарій визначається політикою індексації цієї сторінки.

Приклад повідомлення:

{
"url": "https://example.org/jobs/5281-komirnyk-vinnytsia/",
"type": "URL_UPDATED"
}

Потрібні власність у Search Console, налаштований сервісний обліковий запис, авторизація, черга, облік квот, повторні спроби при тимчасових збоях та журнал подій. Indexing API не можна переносити на довільні сторінки інтернет-магазину, блогу або каталогу: Google обмежує його підтримуваними типами контенту.

Крок 5. Перебудувати sitemap

До sitemap окремих вакансій включаємо доступні, канонічні, актуальні сторінки, які хочемо бачити у Google. Архівні сторінки, якщо вони справді потрібні в пошуку, розглядаємо за загальними правилами sitemap, але не змішуємо з фідом активних вакансій.

lastmod змінюємо лише тоді, коли вміст конкретної сторінки справді оновився. Не варто ставити сьогоднішню дату тисячам URL тільки тому, що сьогодні згенерували XML.

Крок 6. Полагодити внутрішню перелінковку

У категоріях насамперед показуємо відкриті вакансії. Додаємо нормальні HTML-посилання на актуальні сторінки, фільтри за професією та регіоном, зрозумілі повідомлення «Вакансія закрита» і релевантні альтернативи.

Не створюємо мільйони комбінацій фільтрів без окремої цінності: така проблема легко повторила б помилки з фасетною навігацією.

Крок 7. Виправити імпорт дублів

Використовуємо пару «ID джерела + ID роботодавця» та нормалізовані характеристики вакансії. Якщо одна активна вакансія повторно прийшла з фіда, оновлюємо її запис, а не створюємо нову сторінку.

Якщо однакові URL уже існують, звіряємо реальну еквівалентність. 301 доречний для повноцінної заміни; rel=canonical — сигнал щодо дубля, але не спосіб приховати іншу вакансію.

6. Як вимірювати ефект, а не лише радіти зеленим індикаторам

Я б не оцінював цю роботу за кількістю відправлених запитів в Indexing API. API не є лічильником успішних індексацій. Замість цього використовував би п'ять джерел:

База вакансій: скільки реально активних, закритих і дубльованих записів.

Серверні логи: медіанний час до першого підтвердженого звернення Googlebot до нової вакансії (це показник сканування, не індексації).

Google Search Console: кліки й покази URL вакансій, звіт індексації, проблеми розмітки та вибіркова URL Inspection.

Аналітика сайту: органічні переходи, що завершилися поданням заявки.

CRM / база відгуків: кількість валідних звернень на відкриті вакансії, виключення спаму та дубльованих кандидатів.

Порівнювати потрібно рівні 28-денні періоди, зберігаючи однакові правила атрибуції. Зміна числа вакансій, сезонність та реклама здатні вплинути на показники, навіть якщо технічна робота виконана бездоганно.

7. Змодельовані результати через вісім тижнів

Цифри нижче не виміряні на реальному сайті. Вони показують можливу, але не гарантовану картину після комплексу робіт.

Показник за порівнювані 28 днів

До

Після

Зміна

Кліки Google на URL актуальних вакансій

9 200

12 700

+38,0%

Кліки Google на URL закритих вакансій

9 400

4 200

−55,3%

Усі кліки Google на сторінки вакансій

18 600

16 900

−9,1%

Валідні органічні відгуки на відкриті вакансії

164

237

+44,5%

Медіанний час до першого візиту Googlebot, нові вакансії*

32 год

9 год

−71,9%

*Метрика отримана в межах умовних вибірок нових вакансій, із перевіркою Googlebot у логах. Її не можна трактувати як час до індексації чи появи в результатах пошуку.

Парадокс результату: загальна кількість кліків на вакансії зменшилася, але звернень на відкриті позиції стало більше. Це не означає, що зменшення трафіку саме по собі корисне. Ми прибрали багато беззмістовних переходів, а частка відвідувань актуальних вакансій виросла.

Показник валідних відгуків виріс, але не можна приписувати весь приріст лише Indexing API: одночасно змінилися внутрішня навігація, актуальність вмісту, дублювання та інтерфейс відгуку. У реальному проєкті я додатково перевіряв би сезонність і частку вакансій за професіями.

8. Що могло піти не так навіть після виправлень

Помилка 1. Видалити всі архівні URL без інвентаризації. Можна втратити корисні сторінки й зовнішні посилання. Спочатку — цінність, еквіваленти, реферальний трафік і правильна відповідь сервера.

Помилка 2. Залишити JobPosting на закритій вакансії тільки заради пошуку. Це суперечить призначенню розмітки та правилам Google.

Помилка 3. Масово ставити noindex і блокувати ті самі URL в robots.txt. Якщо сторінка закрита для сканування, Google може не побачити тег noindex.

Помилка 4. Надсилати через Indexing API будь-який URL сайту. API має обмежену сферу застосування.

Помилка 5. Вважати відповідь API 200 доказом індексації. Це підтвердження прийняття повідомлення, не гарантія майбутньої появи URL у пошуку.

Помилка 6. Оновлювати дату публікації без реального повторного відкриття позиції. Штучне «омолодження» вакансій підриває довіру та спотворює дані.

Помилка 7. Робити висновок про crawl budget лише за наявністю 12 тисяч URL. Сам Google рекомендує спеціальні заходи з crawl budget насамперед дуже великим або швидко змінюваним сайтам та за наявності відповідних симптомів. Треба дивитися логи, звіти й фактичні затримки, а не одну цифру.

9. Робочий чекліст для SEO-фахівця

Є достовірний статус кожної вакансії та дата його зміни.

Закрита вакансія не дозволяє подати марний відгук.

JobPosting присутній лише там, де реально відкрито набір.

Значення validThrough відповідає реальній даті завершення, якщо дата відома.

На активній сторінці повний опис, роботодавець, місце роботи та працюючий спосіб подання заявки.

Сторінки категорій не містять JobPosting для списку вакансій.

У sitemap немає видалених і неканонічних URL, а lastmod правдивий.

Для нових / змінених вакансій налаштовано Indexing API із журналом, квотами й повторними спробами.

Для видалених URL повертається коректний 404 або 410; нерелевантних масових 301 немає.

Дублікати в імпорті виявляються до створення нового URL.

Категорії пов'язують користувачів передусім з активними вакансіями.

Результат оцінюється за якісними відгуками, а не тільки за числом кліків або API-запитів.

10. FAQ

Чи потрібно видаляти всі закриті вакансії?

Ні, але потрібно своєчасно припиняти показ закритої вакансії як активного оголошення. Якщо сторінка більше не має самостійної користі, 404/`410` зазвичай природніший вибір. Якщо вона цінна як архів, можна залишити її з чітким статусом та без розмітки активної вакансії; рішення про індексацію архіву приймається окремо.

Чи допоможе Indexing API звичайному блогу?

Ні, цей API не призначений для довільних сторінок. Google дозволяє використовувати його для підтримуваних типів, насамперед сторінок із JobPosting та певних сторінок прямих трансляцій із BroadcastEvent.

Чи гарантує JobPosting потрапляння в Google for Jobs?

Ні. Валідна розмітка є однією з передумов можливого спеціального відображення, але не гарантує ні індексації, ні появи в спеціальному інтерфейсі.

Чи потрібно ставити 410 замість 404?

Обидва коди є коректними для остаточно відсутніх сторінок. Вибираємо відповідь відповідно до стану URL і архітектури сайту, а не як «секретний спосіб» прискорити зростання трафіку.

Чи означає падіння загальних кліків провал SEO?

Не завжди. У цьому прикладі зменшилися переходи на неактуальні вакансії, натомість збільшилися якісні відгуки на відкриті. Однак рішення повинно спиратися на бізнес-метрики й контроль альтернативних причин зміни показників.

Висновок

Мені подобається цей кейс тим, що він змінює звичне запитання SEO-фахівця. Замість «Як змусити Google індексувати більше сторінок?» ми починаємо питати: «Які сторінки потрібно показувати саме зараз і чому?»

Для сайту вакансій актуальність — частина якості продукту. Людині не потрібні тисячі красиво оптимізованих сторінок, якщо на більшості з них уже неможливо відгукнутися. Пошуковій системі також потрібно допомогти своєчасно дізнатися, які документи з'явилися, оновилися або перестали бути актуальними.

Практичний урок простий: не кількість URL сама по собі визначає користь SEO, а відповідність сторінки реальному наміру користувача — у потрібний момент часу.

Продовжуйте навчання

Останні матеріали цього курсу

Обговорення та запитання (0)

Поки що тут немає запитань або коментарів. Будьте першим, хто розпочне обговорення.

Додати повідомлення

Тип повідомлення