Beimbet

28 сентября 2026 г. · 4 мин чтения

Сайт на казахском, русском и английском: как сделать правильно

Мы делаем сайты на трёх языках для госорганов, подрядчиков и сервисов - от сайта полиции Жылыойского района до QR-меню на 19 языках. Ниже то, что отличает полноценную мультиязычность от кнопки «перевести», и ошибки, на которых мы учились сами.

Каждому языку - свой адрес

Главная ошибка - переключать язык скриптом на одной и той же странице. Поисковик индексирует адреса, а не состояние кнопки: он увидит одну версию, обычно ту, что показывается по умолчанию, и казахская или английская версия в поиск не попадёт.

Правильно - отдельный адрес для каждого языка: /kk, /ru, /en или поддомены. Тогда каждая версия индексируется отдельно, у каждой свой title и description, и её находят по запросу на своём языке.

hreflang: чтобы поиск показывал нужную версию

Языковые версии одной страницы связывают разметкой hreflang. Каждая версия перечисляет все варианты, включая саму себя, и вариант по умолчанию x-default. Коды языков: kk для казахского, ru для русского, en для английского.

Разметка должна быть взаимной: если казахская страница указывает на русскую, русская обязана указывать на казахскую, иначе поисковик связь проигнорирует. Мы держим список языковых адресов в одной функции и берём его и для страниц, и для sitemap.xml - так две разметки не расходятся.

Переводить нужно не только текст

  • title и meta description каждой страницы
  • превью для соцсетей: заголовок, описание и картинка с текстом на языке страницы
  • alt у изображений
  • разметка schema.org: названия и описания
  • атрибут lang у тега html
  • кнопки, ошибки, подсказки и письма
  • форматы дат, чисел и валюты

Если хоть что-то из этого осталось на русском, казахская версия выглядит недоделанной - и для людей, и для поисковика.

Шрифт должен знать казахские буквы

В казахском алфавите девять букв, которых нет в русском: ә, ғ, қ, ң, ө, ұ, ү, һ, і. Не каждый шрифт их содержит, а если содержит, они часто лежат в отдельном наборе символов cyrillic-ext, который нужно подключить явно.

Когда буквы нет, браузер подставляет её из системного шрифта, и в слове появляется символ другой формы. Мы сами на этом попадались: у моноширинного JetBrains Mono в сборке Google Fonts нет заглавных Ә, Ғ, Қ, Ң, Ұ, Һ, и на этом сайте его пришлось заменить на IBM Plex Mono. Похожая история со знаком тенге: в шрифтах Google Fonts ₸ лежит в расширенном латинском наборе latin-ext, и без него сумма выводится пустым квадратом.

Проверка занимает минуту: наберите на странице «ӘҒҚҢӨҰҮҺІ әғқңөұүһі ₸» каждым шрифтом, который используется на сайте, и посмотрите, не выбивается ли какой-то символ.

Формы слов при числах

В русском у слова после числа три формы: 1 проект, 2 проекта, 5 проектов. В английском две: 1 project, 5 projects. В казахском существительное после числа не меняется: 1 жоба, 5 жоба.

Поэтому склеивать «число + слово» по правилам одного языка нельзя. В браузере и Node.js для этого есть стандартный Intl.PluralRules: он возвращает нужную категорию формы для каждого языка, а сами формы лежат в словаре.

Числа одинаково на сервере и в браузере

Разделитель тысяч в русском и казахском - пробел, в английском - запятая. Если сайт форматирует числа и на сервере, и в браузере, стандартное форматирование может выдать разные пробелы: обычный в одном месте и узкий неразрывный в другом. React видит несовпадение разметки и перерисовывает блок. Мы в итоге задаём разделители явно для каждого языка.

Как переключать язык

  • Переключатель ведёт на ту же страницу на другом языке, а не на главную
  • Язык по настройкам браузера определяем только при входе на корень сайта; на внутренних адресах язык задаёт сам адрес
  • Не перенаправляем по IP-адресу: поисковые роботы приходят из других стран и не увидели бы казахскую версию
  • Названия языков в переключателе пишем на самих языках: Қаз, Рус, Eng

Как не потерять перевод

Когда тексты лежат в словарях по языкам, легко добавить строку в русский и забыть казахский. Мы проверяем это автоматически: тест сравнивает структуру всех словарей и падает, если в каком-то языке не хватает ключа или строка пустая. Так новая страница не уходит в прод наполовину переведённой.

Чек-лист

  • Отдельный адрес для каждого языка
  • Взаимный hreflang и x-default на каждой странице и в sitemap.xml
  • Переведены title, description, превью для соцсетей, alt и разметка
  • Шрифты показывают ә, ғ, қ, ң, ө, ұ, ү, һ, і и ₸
  • Формы слов при числах - по правилам каждого языка
  • Переключатель ведёт на ту же страницу
  • Нет редиректа по IP
  • Автоматическая проверка, что ни один язык не отстал

Статьи по теме

Контакт

Есть задача? Напишите - обсудим

Написать в TelegramНаписать в WhatsApp

Отвечает основатель лично.