← Усі тести

Lowercase-редирект ламає індексацію URL з не-ASCII символами: тест на Googlebot

Гіпотеза
Lowercase-редирект, який зменшує сирий рядок запиту, переводить у нижній регістр і hex-символи percent-кодування. Googlebot нормалізує їх назад до великих, тому для кириличної адреси такий редирект стане петлею, і сторінка не потрапить в індекс. Браузер при цьому відкриє її з кодом 200.
Результат
Підтверджено. За тиждень Googlebot і URL Inspection запитали сторінку 36 разів, щоразу у формі з великими hex, і щоразу отримали 301. Зменшену форму Google не запитав жодного разу, навіть коли вона стояла в sitemap. Chrome, ClaudeBot і QlyzeBot отримали сторінку з кодом 200.

Ідея тесту

«Переадресовуй усі URL на нижній регістр» — одна з найпоширеніших порад у технічному SEO. Вона прибирає дублі на кшталт /Page/ і /page/ і справді працює для простих латинських адрес. Тест перевіряє, що робить таке правило з адресами, де є інші символи. Для прикладу я взяв кирилицю.

Кирилична адреса передається на сервер у percent-кодуванні. Кожен байт UTF-8 записується як % і два hex-символи, тож літера «т» стає %D1%82. Правило, яке зменшує сирий рядок запиту, зменшує й ці символи: %D1%82 перетворюється на %d1%82.

Це стосується не лише кирилиці. Перший байт будь-якого не-ASCII символу в UTF-8 має код від C2 до F4, тож його запис завжди містить hex-літеру. Під удар потрапляють грузинська, грецька чи арабська адреси, латиниця з діакритикою (é = %C3%A9, ł = %C5%82) і закодовані знаки на кшталт коми %2C. Не змінюються лише коди з самих цифр, як-от пробіл %20.

За RFC 3986 обидва записи означають одне й те саме, але стандарт радить приводити hex-символи до великих літер. Якщо краулер робить саме так, він після lowercase-редиректу повертається туди, звідки прийшов. Тест мав показати, чи поводиться так Googlebot.

Як влаштовано тест

Об’єктом тесту стала звичайна на вигляд сторінка /технічний-аудит/ з коротким чеклістом технічного SEO-аудиту. У її вмісті немає жодної згадки про тест, кодування чи редиректи. Сторінку я навмисно зробив звичайною, щоб на поведінку краулерів впливала лише адреса, а не вміст.

Для цієї адреси на сервері працює lowercase-редирект. Якщо сирий рядок запиту відрізняється від запису в нижньому регістрі, сервер відповідає 301 на нього. Для стандартного кодування результат такий самий, як у правила, що бере $request_uri у nginx і зменшує його: %D1%82 стає %d1%82.

На практиці це дає такі відповіді:

ЗапитВідповідь
/%D1%82%D0%B5…%D1%82/ (стандартне кодування, великі hex)301 на нижній регістр
/%d1%82%d0%b5…%d1%82/ (усе в нижньому регістрі)200
нижній регістр з параметром ?utm_source=…200

Тег canonical вказує на зменшену форму, як це зазвичай роблять сайти з lowercase-правилом. Адреса з латиницею без діакритики й закодованих знаків percent-кодування не має, тож для неї такий редирект безпечний.

Як Google мав знайти адресу

До 25 жовтня на сайті не було посилань на цю сторінку. Адреса потрапляла до Google двома шляхами, і обидва давали йому зменшену форму без змін:

  • перевірка в URL Inspection у Search Console, куди я вписав саме зменшену форму;
  • окремий файл sitemap-experiments.xml зі зменшеною адресою, вказаний у robots.txt.

Ці два шляхи показують, чи змінює Google адресу, яку йому дали вже в нижньому регістрі.

25 жовтня я додав посилання на сторінку в цю картку й у статтю про механіку. Посилання записане в стандартному кодуванні з великими hex, як його зробив би будь-який сайт. Як Googlebot поведеться з внутрішнім посиланням, додам у результати.

Результати

Дані зібрано з журналу nginx з 17 по 24 жовтня 2026 року. У таблиці наведено всі звернення Google до сторінки та кілька інших показових клієнтів:

ДатаКлієнтЗапитиЩо сталося
17.10Chromeвеликі hex → 301, далі нижній регістр → 200Сторінка відкрилася після одного редиректу
19.10Google-InspectionTool6 × великі hex → 301 за одну секундуЗменшену форму не запитав
20.10URL Inspection зі зменшеною адресою на вході, двічі24 × великі hex → 301Search Console переписала адресу ще до запиту
20.10Googlebotsitemap-experiments.xml → 200Прочитав зменшену адресу
20.10ClaudeBot1 × нижній регістр → 200Узяв адресу з sitemap без змін
21.10Googlebot Smartphone3 × великі hex → 301 за дві секундиЗменшену форму не запитав
21.10QlyzeBotнижній регістр → 200Узяв адресу без змін
23.10Googlebot Smartphone3 × великі hex → 301Зменшену форму не запитав

Разом Google звернувся до сторінки 36 разів. Усі 36 запитів ішли до форми з великими hex, і всі отримали 301. Жоден клієнт Google не запитав зменшену форму, хоча вона була і в заголовку Location, і в sitemap.

У логах видно сталий патерн. У URL Inspection кожен прохід петлі одним агентом складається рівно з шести запитів: перший і ще п’ять спроб після редиректу. 20 жовтня я перевірив адресу двічі, і щоразу Google окремо пройшов петлю мобільним і десктопним агентом, тож вийшло 24 запити. Звичайний Googlebot робить рівно три запити за візит і зупиняється.

Приклад: один візит Googlebot

Ось три рядки з журналу nginx за 23 жовтня. Шлях скорочено, решту залишено як є:

23/Oct/2026:04:26:22  192.178.4.3  "GET /%D1%82%D0%B5%D1%85…%D1%82/"  301  "…(compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
23/Oct/2026:04:26:24  192.178.4.4  "GET /%D1%82%D0%B5%D1%85…%D1%82/"  301  "…(compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
23/Oct/2026:04:26:24  192.178.4.3  "GET /%D1%82%D0%B5%D1%85…%D1%82/"  301  "…(compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

Кожна відповідь містила Location з адресою в нижньому регістрі. Наступний запит Googlebot знову йшов до великих hex. Після третього запиту він зупинився, так і не отримавши вмісту.

Як перевірено, що це Google

User-Agent легко підробити, тому IP-адреси я перевірив через DNS, як радить Google. Усі запити Google прийшли з трьох адрес: 192.178.4.3, 192.178.4.4 і 192.178.4.5. Зворотний DNS для них повертає імена crawl-192-178-4-x.googlebot.com, а прямий запит до імені повертає ту саму IP-адресу.

Ця перевірка відсіяла один фальшивий запит. 23 жовтня «bingbot» прочитав sitemap з IP-адреси Google Cloud, а справжній Bing використовує мережі Microsoft. Цей запит я до результатів не включав.

Висновки

Lowercase-редирект, який зменшує сирий рядок запиту, ламає індексацію сторінок з не-ASCII символами в адресі. Кирилиця в цьому тесті лише приклад. Google приводить hex-символи до великих літер ще до першого запиту, з якого б джерела не взяв адресу. Тому зменшена форма для нього недосяжна, а редирект на неї перетворюється на петлю.

Людина цієї проблеми не помітить. У моєму тесті Chrome узяв адресу з Location як є і відкрив сторінку після одного редиректу. ClaudeBot і QlyzeBot теж отримали сторінку, тож зламаною вона виявилася лише для Google.

Відмовлятися від lowercase-редиректу не обов’язково, але його варто перевірити на не-ASCII адресах. Ось на що дивитися:

  • правило переводить у нижній регістр декодований шлях, а не рядок, де є %XX;
  • адреси, що відрізняються лише регістром hex-символів, не отримують редиректу;
  • canonical і sitemap містять стандартну форму з великими hex;
  • адреса з великими hex відповідає 200 або веде на 200 за один крок.

Найпростіша перевірка займає хвилину. Запроси адресу з кирилицею, діакритикою чи закодованим знаком у стандартному кодуванні з великими hex через curl -sI і подивись на заголовок Location. Якщо там з’явилися малі hex, сайт має ту саму проблему.

Що далі

Тест я продовжую спостерігати. Чекаю, що покаже звіт «Сторінки» в Search Console для цієї адреси і як Googlebot пройде за внутрішнім посиланням. Справжній Bingbot до сторінки ще не приходив, тож його поведінку додам окремо.

Джерела

Механіка спирається на стандарт URI та документацію Google. Поведінку браузера й краулерів я брав з логів власного сервера. Ось першоджерела:

Чому так стається, як налаштувати lowercase-редирект безпечно і як перевірити свій сайт, я розібрав у статті «Як lowercase-редирект ламає індексацію URL з кирилицею та іншими не-ASCII символами».