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.10 | Chrome | великі hex → 301, далі нижній регістр → 200 | Сторінка відкрилася після одного редиректу |
| 19.10 | Google-InspectionTool | 6 × великі hex → 301 за одну секунду | Зменшену форму не запитав |
| 20.10 | URL Inspection зі зменшеною адресою на вході, двічі | 24 × великі hex → 301 | Search Console переписала адресу ще до запиту |
| 20.10 | Googlebot | sitemap-experiments.xml → 200 | Прочитав зменшену адресу |
| 20.10 | ClaudeBot | 1 × нижній регістр → 200 | Узяв адресу з sitemap без змін |
| 21.10 | Googlebot Smartphone | 3 × великі hex → 301 за дві секунди | Зменшену форму не запитав |
| 21.10 | QlyzeBot | нижній регістр → 200 | Узяв адресу без змін |
| 23.10 | Googlebot Smartphone | 3 × великі 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. Поведінку браузера й краулерів я брав з логів власного сервера. Ось першоджерела:
- RFC 3986: розділ 2.1 про percent-кодування й розділ 6.2.2.1 про нормалізацію регістру hex-символів;
- Google: переадресації та Google Search;
- Google: перевірка запитів від краулерів Google;
- Google: поширені краулери, зокрема Google-InspectionTool;
- Довідка Search Console: інструмент перевірки URL.
Чому так стається, як налаштувати lowercase-редирект безпечно і як перевірити свій сайт, я розібрав у статті «Як lowercase-редирект ламає індексацію URL з кирилицею та іншими не-ASCII символами».