Темы и внешний вид Web App

Темы и внешний вид Web App
Заголовок раздела «Темы и внешний вид Web App»Web App поддерживает файловые темы, предпросмотр и базовую настройку внешнего вида из админ-панели. Тема может быть простой цветовой схемой на JSON-токенах или полноценным скином с собственным CSS, шрифтами, иконками и графикой.
Что можно поменять
Заголовок раздела «Что можно поменять»Через раздел Админка -> Внешний вид можно:
- выбрать глобальную тему Web App;
- изменить accent-цвет конкретной темы;
- включить или выключить применение темы в админ-панели;
- настроить масштаб логотипа на главной и экране входа;
- загрузить логотип файлом или по HTTPS-ссылке;
- включить emoji-логотип и выбрать способ его отрисовки;
- открыть предпросмотр темы через
/home?theme_preview=<key>.
Через файлы темы можно менять намного больше:
- базовые цвета Mini App и админки;
- радиусы, семейства шрифтов и размер главного логотипа;
- любые компоненты через CSS: карточки, навигацию, таблицы, модалки, кнопки, скелетоны, прогресс-бары, состояния hover/active и мобильную/desktop-верстку;
- экран инструкций установки (
/installи/s/<token>): topbar, выбор платформы, карточки приложений, шаги инструкции и QR-блок личной страницы; - иконки и изображения, если CSS ссылается на ассеты темы;
- стили только пользовательской части, только админки или обеих частей сразу.
Готовые темы лежат в backend/bot/app/web/themes: dark, light, windows95, ascii. При первом запуске они копируются в WEBAPP_THEMES_DIR, по умолчанию data/themes.
Где живут темы
Заголовок раздела «Где живут темы»Каждая тема - отдельная папка:
Путь настраивается переменной:
WEBAPP_DEFAULT_THEME опционален. Если он задан и совпадает с ключом темы, он переопределяет default: true в theme.json. Если переменная пустая, дефолт выбирается из дескрипторов тем.
Важно: WEBAPP_PRIMARY_COLOR, WEBAPP_LOGO_URL, WEBAPP_LOGO_USE_EMOJI, WEBAPP_LOGO_EMOJI и WEBAPP_LOGO_EMOJI_FONT больше не являются рабочим способом первичной настройки через .env. Эти значения редактируются в админке и сохраняются как overrides в базе. Тема при этом может использовать сохраненный primary color как fallback accent.
Контракт theme.json
Заголовок раздела «Контракт theme.json»Минимальная тема:
Тема с CSS:
Поля верхнего уровня:
| Поле | Назначение |
|---|---|
key | Уникальный ключ темы, 1-64 символа: латиница, цифры, _ и -. Если ключ не указан, берется имя папки. |
names | Локализованные названия, например ru и en. |
enabled | Показывать тему пользователям. Отключенная тема не попадает в публичный каталог. |
default | Делает тему выбранной по умолчанию, если WEBAPP_DEFAULT_THEME не задан. |
use_primary_accent | Если true, тема может получить accent из настройки внешнего вида, когда в tokens.accent ничего нет. |
use_in_admin | Если false, пользовательская часть использует тему, но админка откатывается на dark. |
css_file | CSS-файл внутри папки темы. Может быть style.css или вложенный путь вроде css/theme.css. |
assets_version | Версия ассетов. Для встроенных тем используется для обновления старых файлов в data/themes. |
tokens | Дизайн-токены, которые превращаются в CSS-переменные на .app-shell. |
Поддерживаемые токены:
| Токен | CSS-переменная | Что меняет |
|---|---|---|
color_scheme | color-scheme | Нативная светлая/темная схема браузера: dark или light. |
style_preset | CSS-класс пресета | Сейчас win95/windows95 добавляет theme-preset-win95; остальные значения не дают специального класса. |
accent | --accent | Главный акцент: активные элементы, кнопки, прогресс, фокус. Только hex #RGB или #RRGGBB. |
bg | --bg | Основной фон приложения. |
panel | --panel | Основные карточки и поверхности. |
panel_2 | --panel-2 | Вторичные поверхности. |
panel_3 | --panel-3 | Поверхности повышенной вложенности, dropdown/popover. |
border | --border | Обычные границы. |
border_strong | --border-strong | Усиленные границы и hover-состояния. |
text | --text | Основной текст. |
muted | --muted | Вторичный текст. |
dim | --dim | Еще более тихий текст и служебные подписи. |
danger | --danger | Ошибки и опасные действия. |
blue | --blue | Синий вспомогательный цвет. |
radius | --radius | Базовый радиус карточек, кнопок и контролов. |
font_sans | --font-sans | Основной шрифт интерфейса. |
font_logo | --font-logo | Шрифт бренда и заголовка. |
font_mono | --font-mono | Моноширинный шрифт. |
home_logo_scale | --home-logo-scale | Масштаб логотипа на главной и входе, от 50 до 300 процентов. |
admin_bg | --admin-bg | Фон админ-панели. |
admin_surface | --admin-surface | Основные карточки админки. |
admin_surface_2 | --admin-surface-2 | Вторичные поверхности админки. |
admin_elev | --admin-elev | Elevated-поверхности админки. |
admin_border | --admin-border | Границы админки. |
admin_border_strong | --admin-border-strong | Усиленные границы админки. |
admin_text | --admin-text | Основной текст админки. |
admin_muted | --admin-muted | Вторичный текст админки. |
admin_dim | --admin-dim | Тихие подписи админки. |
Если css_file не задан, интерфейс полностью строится на токенах и общих стилях. Если css_file задан, токены все равно применяются первыми, а CSS темы может уточнить или полностью переопределить внешний вид.
CSS-слой темы
Заголовок раздела «CSS-слой темы»CSS темы подключается как:
Например data/themes/neon/style.css будет доступен как /webapp-theme-css/neon/style.css.
Корневой контейнер получает классы:
Для светлой схемы будет theme-light. Класс theme-key-<key> - основной якорь для CSS темы. Всегда начинайте селекторы с него, чтобы тема не задевала другие режимы:
CSS можно писать для пользовательской части и админки одновременно:
Ограничения:
- CSS-файл должен быть внутри папки темы;
- размер CSS - до 512 KiB;
- путь не может содержать
..; - удаленные CSS,
data:и protocol-relative URL вcss_fileне подключаются.
Ассеты темы
Заголовок раздела «Ассеты темы»Картинки темы кладутся рядом с theme.json и отдаются через:
Пример:
Разрешены png, jpg, jpeg, gif, webp, svg, ico. Один asset - до 1 MiB. Для шрифтов лучше использовать внешние источники, уже разрешенные CSP (fonts.googleapis.com, fonts.gstatic.com, cdn.jsdelivr.net) или системные fallback-цепочки в font_* токенах.
Пайплайн создания новой темы
Заголовок раздела «Пайплайн создания новой темы»-
Выберите ключ темы.
Ключ должен быть стабильным: по нему сохраняется выбранная тема и строятся URL ассетов. Используйте короткий slug:
neon,brand_dark,terminal-blue. Не переименовывайте ключ после публикации без миграции файлов и сохраненных настроек. -
Создайте папку в
WEBAPP_THEMES_DIR.В Docker по умолчанию это
data/themes. Если включен bind mount./data:/app/data, убедитесь, что контейнер может писать вdata. -
Скопируйте ближайшую базовую тему.
Для обычной брендовой темы чаще всего удобнее начать с
darkилиlight. Для глубокого CSS-скина можно взятьasciiилиwindows95как пример того, насколько далеко можно уйти от стандартного вида. -
Отредактируйте
theme.json.Сначала поменяйте
key,names,default,use_primary_accentи базовые токены. На этом этапе можно вообще не создавать CSS: приложение уже увидит тему как новый набор токенов. -
Запустите приложение и откройте админку.
Раздел Внешний вид загружает
/api/admin/themes, backend читаетWEBAPP_THEMES_DIR, добавляет обязательные базовые темы и возвращает каталог. Нажмите Обновить, если папка была создана во время работы приложения. -
Проверьте тему через предпросмотр.
В карточке темы нажмите Предпросмотр или откройте:
Предпросмотр не меняет глобальную тему и удобен для проверки CSS до публикации.
-
Подберите accent и масштаб логотипа.
В админке можно менять accent и
home_logo_scaleбез ручного редактирования JSON. При сохранении backend перепишетtheme.jsonвWEBAPP_THEMES_DIR, выставит ровно одинdefaultи сбросит кеш публичных настроек. -
Добавьте
style.css, если токенов мало.Создайте файл, укажите его в
theme.json:Начинайте с переопределения CSS-переменных на
.theme-key-neon.app-shell, затем переходите к конкретным компонентам. Проверяйте минимум: главная,/install, публичная/s/<token>, оплата, настройки, модалки, админский дашборд, таблица пользователей, редактор тарифов. -
Добавьте ассеты при необходимости.
Положите картинки в подпапку темы и ссылайтесь на них через
/webapp-theme-assets/<key>/.... Не используйте относительные пути вродеurl("icons/x.png"), если CSS может быть подключен с другого URL-уровня; явный/webapp-theme-assets/neon/icons/x.pngнадежнее. -
Настройте поведение админки.
Если тема сильно декоративная и мешает рабочей админке, выставьте
use_in_admin: false. Пользователи увидят тему, а администраторы в разделе админки получатdarkкак fallback. -
Сделайте тему дефолтной.
Есть два способа:
- в админке выбрать тему и сохранить;
- указать
WEBAPP_DEFAULT_THEME=neonв.env, если нужен жесткий override на уровне окружения.
-
Зафиксируйте тему.
Для темы, которая должна ехать вместе с проектом, добавьте ее в репозиторий в
backend/bot/app/web/themesи при необходимости расширьтеDEFAULT_THEME_KEYSвbackend/config/webapp_themes_config.py. Для приватной инсталляции достаточно хранить ее вdata/themes.
Насколько глубоко можно менять вид
Заголовок раздела «Насколько глубоко можно менять вид»Уровни кастомизации:
- Быстрый бренд - токены
accent,bg,panel,text,radius, логотип в админке. Код не нужен. - Полная палитра - все пользовательские и admin-токены, отдельные шрифты, масштаб логотипа.
- CSS-скин - переопределение карточек, навигации, таблиц, модалок, progress/skeleton/toast, desktop/mobile раскладок.
- Почти новый UI - тема вроде
windows95илиascii: можно менять форму контролов, иконки, эффекты, таблицы и визуальный язык целиком, пока сохраняется DOM и интерактивные состояния.
Не стоит менять через CSS смысловые состояния: скрывать ошибки, отключать фокус, перекрывать кнопки невидимыми слоями или делать display: none для обязательных действий оплаты и авторизации. Тема должна менять внешний вид, а не бизнес-логику.
Диагностика
Заголовок раздела «Диагностика»Если тема не появилась:
- проверьте, что
theme.jsonлежит ровно вWEBAPP_THEMES_DIR/<key>/theme.json; - ключ состоит только из латиницы, цифр,
_и-; - JSON валиден;
- тема не отключена через
enabled: false; - в логах нет предупреждения
Ignoring theme descriptor.
Если CSS не применился:
- проверьте
css_fileи URL/webapp-theme-css/<key>/<css_file>; - убедитесь, что файл меньше 512 KiB;
- начинайте селекторы с
.theme-key-<key>; - откройте
/home?theme_preview=<key>в новом окне, чтобы исключить сохраненный старый выбор.
Если ассеты не грузятся:
- используйте путь
/webapp-theme-assets/<key>/<path>; - проверьте расширение:
png,jpg,jpeg,gif,webp,svg,ico; - размер каждого файла должен быть до 1 MiB;
- путь не должен содержать пробелы, кириллицу или
...