Интернационализация dix.su¶
Вывод по домену: один домен, не два¶
Рекомендация: один домен dix.su, мультиязычный контент.
Два домена (например dix.su для РФ и dixsu.com для иностранцев) выглядят
логично, но создают больше проблем, чем решают:
| Один домен | Два домена | |
|---|---|---|
| Кодовая база | один деплой | два деплоя, два .env, два CI |
| Пользователи | единая БД, один аккаунт | аккаунты раздвоены навсегда |
| SEO | весь трафик на одном домене | split — каждый домен слабее |
| Платёжные провайдеры | уже разделены по коду (Tinkoff/LS) | та же логика, дважды |
| GDPR vs 152-FZ | решается политиками и UX, не доменом | видимость решения без реальной выгоды |
Пользователь из РФ, переехавший за рубеж, не должен заводить второй аккаунт. Технический специалист из Европы не должен попадать на «не ту» версию сайта.
Как разграничить RU и международный контент без второго домена¶
- Язык интерфейса — по
Accept-Languageбраузера + ручной переключатель - Платёжный провайдер — уже определяется в
BillingControllerпо конфигурации (tinkoffAvailable/lsAvailable); в будущем можно добавить гео-детектор - Юридические документы —
/privacyи/termsс языковым переключателем (или/ru/privacy,/en/privacyкак отдельные страницы) - Cookie consent — показывается всем, но особенно важен для EU пользователей
Что реально требует GDPR (если есть EU-пользователи)¶
GDPR применяется при целенаправленном предложении услуг жителям ЕС.
Обязательно¶
- Cookie consent — баннер при первом визите, нельзя использовать аналитические/маркетинговые куки до согласия
- Privacy Policy на английском — право на удаление данных (right to erasure), право на экспорт данных, контакт DPO или ответственного лица
- Механизм удаления аккаунта — кнопка «Delete account» в личном кабинете (сейчас есть?)
Рекомендуется¶
- Явное согласие при регистрации (чекбокс «I agree to Privacy Policy») — сейчас есть согласие на 152-FZ, добавить GDPR формулировку
- Отдельный email для privacy-запросов (напр.
privacy@dix.su)
Не требуется для начала¶
- Отдельный DPO (Data Protection Officer) — нужен только при масштабах
- Отдельный сервер в EU — технически рекомендуется, но на старте не критично
Что требует 152-FZ (российские пользователи)¶
Уже выполнено на текущей инфраструктуре: - Данные российских пользователей хранятся на российских серверах ✅ (VPS 217.114.43.49 — российский хостинг) - Согласие на обработку персональных данных при регистрации ✅ - Политика конфиденциальности на русском ✅
Статус реализации (актуально на 2026-08-02)¶
✅ Шаг 1 — Cookie consent — реализован¶
Баннер cookieBanner во всех публичных и защищённых шаблонах через Thymeleaf-фрагмент
fragments/site-layout :: cookieBanner. Флаг в localStorage.
✅ Шаг 2 — Правовые документы на английском — реализованы¶
/en/privacy, /en/terms, /en/aup — маршруты в LandingController, шаблоны
privacy-en.html, terms-en.html, aup-en.html.
✅ Шаг 3 — Английская landing page и контентные страницы — реализованы¶
/en/→landing-en.html/en/faq→faq-en.html- Контентные страницы (
/tunnel,/services,/profile,/shortlinks,/catalog,/clarity,/otzovik) — двуязычные через#{key}изmessages_en.propertiesи/илиth:if="${#locale.language == 'en'}"блоки.
✅ Шаг 4 — Language switcher — реализован¶
/set-lang?lang=en / /set-lang?lang=ru → сохраняет язык в сессию через
LocaleChangeInterceptor. Переключатель в навигации на публичных страницах.
✅ Шаг 5 — i18n публичных шаблонов — реализован¶
messages.properties (RU) + messages_en.properties (EN) покрывают landing,
services, tunnel-landing и другие публичные страницы.
❌ Шаг 6 — Полный i18n защищённых страниц — не начато¶
protected-page.html (личный кабинет), admin.html и другие LK-шаблоны
не переведены — строки хардкодены на русском. Это самый трудоёмкий шаг;
можно делать итеративно, начиная с раздела биллинга.
❌ Шаг 7 — Английская документация (dix.su/docs/) — не начато¶
Текущий mkdocs.yml задаёт language: ru. Варианты реализации —
см. раздел «Английская документация» ниже.
Что НЕ нужно делать¶
- Второй домен — см. выше, только усложняет
- Отдельный сервер в ЕС — до ~1000 EU пользователей не критично
- Перевод всего сразу — лучше английский landing + ключевые экраны, чем полный перевод плохого качества
- Отдельная БД для иностранных пользователей — все в одной базе, разница только в платёжном провайдере
Где смотреть код для i18n¶
| Файл | Что |
|---|---|
modulauth/.../config/WebConfig.java |
LocaleChangeInterceptor, AcceptHeaderLocaleResolver |
modulauth/src/main/resources/messages*.properties |
Файлы переводов (создать) |
templates/protected-page.html |
Основной UI — строки заменить на #{key} |
templates/interstitial_plug.ex (dixu_proxy) |
Интерстициальная страница туннеля |
Английская документация (dix.su/docs/)¶
Текущая docs-сборка — monolingual Russian (language: ru в mkdocs.yml).
Вариант A — Community plugin mkdocs-static-i18n (рекомендуется, бесплатно)¶
Добавить pip install mkdocs-static-i18n в docsite/Dockerfile (стейдж builder):
Структура файлов:
docs/
README.md ← RU (по умолчанию)
README.en.md ← EN-версия
BILLING.md
BILLING.en.md
guides/
tcp-tunnel-clients.md
tcp-tunnel-clients.en.md
В mkdocs.yml — добавить plugin:
Итог: появляется переключатель языка в шапке docs-сайта; каждая страница
доступна на обоих языках. Файлы без .en.md пары остаются только на RU.
Вариант B — Отдельная секция EN в nav (проще, но без переключателя)¶
Без плагинов — просто добавить в mkdocs.yml:
nav:
- ...текущая навигация...
- "─── English ───":
- Overview: en/README.md
- Billing: en/BILLING.md
- TCP tunnel: en/guides/tcp-tunnel-clients.md
Создать docs/en/ с переведёнными ключевыми страницами вручную.
Минус: нет связи между языковыми версиями страниц.
Что переводить в первую очередь¶
| Страница | Приоритет | Почему |
|---|---|---|
README.md |
высокий | первая страница для новых пользователей |
guides/tcp-tunnel-clients.md |
высокий | технические команды, нужны EN-пользователям |
BILLING.md |
средний | нужен при Lemon Squeezy активации |
SECURITY.md |
средний | E2E и приватный режим |
guides/custom-domain.md |
средний | частый запрос |
Внутреннюю документацию (ARCHITECTURE.md, MODULES.md, DEPLOYMENT.md)
переводить не нужно — она адресована разработчику платформы (одному человеку).