Files
andreypr207andClaude Opus 5.5 20491d1ba4 Этап 1b: сайт
- Страницы обоих брендов из блоков Payload (D-029): главная, цены,
  локации, поддержка, 4 юридические, 404 и 500. Коллекции pages
  (черновики и версии) и faq с местами показа, 12 типов блоков; поля
  sites — почта и Telegram поддержки, часы работы, SEO по умолчанию.
- Карта и глобус рисуются на сервере (d3-geo), контуры во внешнем
  SVG через <use>; выбор локации синхронизирован между картой и сеткой.
- Тексты сайта и юридические черновики на 5 языках: de, fr, es —
  перевод с глоссарием; seed создаёт страницы и FAQ, только если их
  нет, SEED_CONTENT=reset пересоздаёт.
- SEO: title и описания, canonical, hreflang с x-default,
  sitemap.xml и robots.txt на каждый домен, картинки для соцсетей.
- Статическая сборка и пересборка через revalidatePath из хуков
  Payload (D-030); /svc/internal/revalidate для проверки.
- 404 — статичная страница со статусом 404 через proxy; на сайте
  только опубликованные страницы.
- Производительность: Client Hints темы Payload только в админке,
  предзагрузка 2 файлов шрифтов вместо 6; Lighthouse mobile 97–99.
- Контраст --ink-3 по WCAG AA, радиокнопки вместо div role=button.
- Документация: итоги 1b, глоссарий de/fr/es, трактовки юридических
  черновиков подтверждены, переносимые вопросы — в этапах 3e–3h.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 04:53:15 +02:00

93 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 06. Языки и валюты на сайте
## 1. Языки
1. Сейчас: `en` (по умолчанию), `ru`, `de`, `fr`, `es`.
2. Позже: `pt-br` (бразильский португальский) и `ja`. Для японского понадобится запасной шрифт: Commissioner и Unbounded не содержат японских знаков.
3. Список языков задаётся в конфиге Payload и next-intl (код). У каждого домена в базе — включённые языки и язык по умолчанию.
4. Интерфейс админки — `ru` и `en`.
## 2. Два слоя переводов
| Что | Где | Кто правит |
|---|---|---|
| Интерфейс: кнопки, подписи, ошибки, сообщения форм | `src/i18n/messages/{en,ru,de,fr,es}.json`, next-intl | разработка, через git |
| Контент: тарифы, локации, FAQ, страницы, шаблоны писем, тексты бота | локализованные поля Payload | админка, без деплоя |
1. В коде компонентов нет строк на конкретном языке, только ключи переводов.
2. Нет перевода на языке — показывается английский. Отдельная проверка выводит список непереведённых ключей.
3. Множественные числа — ICU в next-intl: «12 серверов», «3 сервера», «1 сервер».
## 3. URL
1. Английский без префикса, остальные — с префиксом: `veilix.app/pricing`, `veilix.app/ru/pricing`, `veilix.app/de/pricing`. Точнее, без префикса открывается язык домена по умолчанию (`domains.defaultLocale`, сейчас везде en), а адрес с его префиксом (`/en/pricing`) перенаправляется на адрес без префикса.
2. Так же в кабинете: `my.veilix.app/keys`, `my.veilix.app/ru/keys`.
3. MiniApp: адрес в BotFather один, поэтому язык берётся из профиля пользователя или из Telegram; префикс в URL необязателен.
4. Пути одинаковые для всех языков (английские): `/pricing`, `/locations`, `/support`, `/legal/terms`, `/keys`, `/billing`, `/referral`, `/order`, `/login`.
5. Язык, не включённый на домене, — 404.
## 4. Определение языка
1. Порядок: язык из URL → выбранный ранее (cookie `NEXT_LOCALE`, у вошедшего — язык профиля) → язык браузера (`Accept-Language`) среди включённых → страна из заголовка nginx `X-Geo-Country` (MaxMind) → `en`.
2. Перенаправление на версию с префиксом — с адреса без префикса и только если выбран не язык домена по умолчанию ([D-024](decisions/D-024-locale-redirect.md)). Есть cookie `NEXT_LOCALE` — ведём на язык из cookie; cookie нет — определяем по языку браузера и стране. Перенаправляются только GET и HEAD. Поисковых ботов не перенаправляем никогда: так рекомендует Google.
3. Переключатель языка ставит cookie `NEXT_LOCALE`. У вошедшего пользователя язык сохраняется ещё и в профиле: на нём уходят письма и сообщения бота.
4. Соответствие стран языкам по умолчанию: RU, BY, KZ, KG → ru; DE, AT → de; FR → fr; ES и испаноязычные страны Латинской Америки → es (Бразилия — en, пока нет pt-br); остальные → en. Таблица — `src/core/routing/locale.ts`.
## 5. SEO
1. `hreflang` на все включённые языки и `x-default` на английскую версию.
2. `canonical` на основной домен, в том числе с зеркал.
3. `sitemap.xml` для каждого маркетингового домена с вариантами всех языков. `robots.txt` — на каждый домен: индексация разрешена только маркетинговым доменам с флагом `indexable`, остальным закрыто всё. Оба файла proxy переписывает на `/svc/seo/{домен}/…`.
4. Кабинет и MiniApp не индексируются (`noindex`).
5. Атрибут `lang` у `<html>` соответствует языку страницы.
6. `<title>`: у главной — свой заголовок целиком, у остальных страниц — по шаблону сайта `sites.seo.titleTemplate` («%s · Вейликс»). Описание — из `pages.seo`, иначе описание сайта. Плейсхолдеры цен и числа стран в них заполняются.
7. Картинка для соцсетей: своя у страницы (`pages.seo.image`) или сайта (`sites.seo.ogImage`), иначе создаётся `/svc/og/{сайт}/{язык}/{страница}` — 1200×630, заголовок страницы в цветах бренда.
8. 404 отдаётся со статусом 404 и `noindex`.
## 6. Валюта
1. Переключатель валюты отдельный от языка, стоит рядом с переключателем языка в шапке и подвале. В макете его нет — добавляется в стиле переключателя языка.
2. Валюта не определяется по стране: из России часто заходят через VPN.
3. По умолчанию — валюта домена для языка (`domains.localeCurrency`: ru → RUB), иначе `domains.defaultCurrency` (USD).
4. Выбор хранится в cookie `vx_currency`. Валюта не входит в URL: маркетинговые страницы заранее собраны во всех валютах, proxy выбирает вариант по cookie. Поисковые боты видят валюту по умолчанию.
5. Ссылка «Купить» передаёт валюту в оформление заказа (`?currency=`). У вошедшего пользователя в кабинете всегда валюта аккаунта ([04-billing.md](04-billing.md), раздел 2).
6. Форматирование — `Intl.NumberFormat` с узким символом валюты: «4 900 ₽» в русском, «₽4,900» в английском, «$49». Неразрывные пробелы ставит Intl. Даты — `Intl.DateTimeFormat`: «14 октября 2026».
## 7. Как переводим
1. Источник: русские тексты макетов и английские из словаря макета `design/handoff/project/i18n.js` (около 515 строк). Интерфейс ложится в `messages/*.json`, тексты страниц и остальной контент — в Payload ([D-029](decisions/D-029-pages-blocks.md)).
2. Немецкий, французский, испанский переводит Claude с глоссарием в каждом этапе, вместе с RU и EN ([D-033](decisions/D-033-translations.md)). Вычитки носителями нет, поэтому глоссарий и контекст обязательны. Финальная проверка — на публичном запуске (этап 3h).
3. В юридических текстах пункт: «При расхождениях между версиями действует английская».
4. Новая строка интерфейса или контента сразу появляется на 5 языках.
## 8. Глоссарий
| RU | EN | DE | FR | ES | Примечание |
|---|---|---|---|---|---|
| Вейликс / ВейликсВПН | Veilix / VeilixVPN | Veilix / VeilixVPN | Veilix / VeilixVPN | Veilix / VeilixVPN | не переводится |
| ключ | key | Schlüssel | clé | clave | купленная единица доступа |
| локация | location | Standort | emplacement | ubicación | |
| тариф | plan | Tarif | forfait | plan | |
| подписка | subscription | Abonnement | abonnement | suscripción | у mass на сайте |
| подключение | connection | Verbindung | connexion | conexión | |
| устройство | device | Gerät | appareil | dispositivo | |
| индивидуальный IP | dedicated IP | dedizierte IP-Adresse | IP dédiée | IP dedicada | |
| RU-адрес, российский адрес | RU address, Russian address | RU-Adresse, russische Adresse | adresse RU, adresse russe | dirección RU, dirección rusa | |
| кабинет | account | Kundenkonto | espace client | área de cliente | |
| баланс, счёт | balance | Guthaben | solde | saldo | |
| пополнить | top up | aufladen | recharger | recargar | |
| продление, автопродление | renewal, auto-renewal | Verlängerung, automatische Verlängerung | renouvellement, renouvellement automatique | renovación, renovación automática | |
| льготный период | grace period | Kulanzfrist | délai de grâce | período de gracia | |
| реферальная программа | referral program | Empfehlungsprogramm | programme de parrainage | programa de referidos | |
| серверы в наличии | servers available | Server verfügbar | serveurs disponibles | servidores disponibles | статус локации dedicated |
| установим за 24 часа | ready within 24 hours | in 24 Stunden bereit | prêt sous 24 heures | listo en 24 horas | статус локации dedicated |
| включено | included | inklusive | inclus | incluido | статус локации mass |
| скоро | coming soon | in Kürze | bientôt | próximamente | статус локации mass |
| цены | pricing | Preise | Tarifs | Precios | пункт меню и страница; тариф как продукт — по строке «тариф» |
| поддержка | support | Support | Assistance | Soporte | |
| войти | log in | Anmelden | Se connecter | Entrar | кнопка в шапке шириной 78 px |
| счёт и платежи | billing | Guthaben & Zahlungen | Facturation | Saldo y pagos | раздел кабинета |
| документы | legal | Rechtliches | Informations légales | Legal | раздел подвала; во Франции «Mentions légales» — отдельная обязательная страница |
Обращение к пользователю: de — «Sie», fr — «vous», es — «tú» (как принято у потребительских сервисов в Испании и Латинской Америке). Типографика: de — кавычки „…“ и короткое тире « – »; fr — « … » и неразрывный пробел перед `: ; ? !`; es — «…», ¿…? и ¡…!. Длинные немецкие слова в узких местах — с мягким переносом (U+00AD). Названия протоколов и приложений (WireGuard, AmneziaWG, Xray, VLESS, Hysteria2, XHTTP, Happ) не переводятся.