Тема и элементы управления
Тема и элементы управления определяют, насколько «родным» ваше Mini App будет выглядеть внутри Telegram. Пользователи ожидают, что приложение адаптируется к их теме (светлая/тёмная), использует нативные цвета и шрифты Telegram. Приложение с чужим дизайном теряет доверие пользователей и снижает конверсию.
Mini App должно выглядеть как естественная часть Telegram — не как внешний сайт, открытый в браузере. Для этого платформа предоставляет систему тем через CSS-переменные и нативные UI-контроллы.
Система тем
Telegram передаёт цвета текущей темы пользователя через CSS-переменные, которые автоматически доступны в вашем приложении:
/* Основные переменные темы */
var(--tg-theme-bg-color) /* фон приложения */
var(--tg-theme-text-color) /* основной текст */
var(--tg-theme-hint-color) /* подсказки, placeholder */
var(--tg-theme-link-color) /* ссылки */
var(--tg-theme-button-color) /* кнопки */
var(--tg-theme-button-text-color) /* текст кнопок */
var(--tg-theme-secondary-bg-color) /* вторичный фон */
Пример использования:
body {
background-color: var(--tg-theme-bg-color);
color: var(--tg-theme-text-color);
}
.card {
background-color: var(--tg-theme-secondary-bg-color);
border-radius: 12px;
padding: 16px;
}
a {
color: var(--tg-theme-link-color);
}
Всегда ставьте фон приложения = var(--tg-theme-bg-color)
Это создаёт эффект бесшовной интеграции — пользователь не видит границу между Telegram и Mini App. Если ваш фон отличается от темы Telegram, приложение выглядит инородно.
Смена темы
Пользователь может переключить тему Telegram (светлая/тёмная) прямо во время работы Mini App. Приложение должно отреагировать:
// Подписка на изменение темы
WebApp.onEvent('themeChanged', () => {
// CSS-переменные обновляются автоматически
// Но если вы кэшировали цвета в JS -- обновите их
const bg = WebApp.themeParams.bg_color;
const text = WebApp.themeParams.text_color;
console.log('Тема изменилась:', { bg, text });
});
Если вы используете CSS-переменные напрямую — обновление произойдёт автоматически. Проблемы возникают только когда цвета хранятся в JavaScript-переменных или inline-стилях.
MainButton
MainButton — главная кнопка действия, расположенная в самом низу экрана. Это стандартный паттерн UI Mini App для основного действия:
Пример использования с @telegram-apps/sdk-react:
import { useEffect } from 'react';
import { mainButton } from '@telegram-apps/sdk-react';
function CheckoutPage() {
useEffect(() => {
// Настройка кнопки
mainButton.setParams({
text: 'Оформить заказ',
isVisible: true,
isEnabled: true,
});
// Обработчик нажатия
const off = mainButton.onClick(() => {
mainButton.setParams({ isLoading: true });
submitOrder().finally(() => {
mainButton.setParams({ isLoading: false });
});
});
// Очистка
return () => {
off();
mainButton.setParams({ isVisible: false });
};
}, []);
return <div>Ваш заказ...</div>;
}
Ключевые свойства MainButton:
- text — текст кнопки
- isVisible — показать/скрыть
- isEnabled — активная/неактивная
- isLoading — индикатор загрузки (спиннер)
- color / textColor — цвета (по умолчанию из темы)
BackButton
BackButton — кнопка “назад” в верхнем левом углу. Используется для навигации между экранами внутри Mini App:
import { useEffect } from 'react';
import { backButton } from '@telegram-apps/sdk-react';
function ProductDetails({ onBack }) {
useEffect(() => {
backButton.show();
const off = backButton.onClick(() => {
onBack(); // возврат на предыдущий экран
});
return () => {
off();
backButton.hide();
};
}, [onBack]);
return <div>Описание товара...</div>;
}
Паттерн навигации
MainButton — для основного действия (CTA), BackButton — для навигации назад. Это стандартный UX-паттерн всех Mini App. Не создавайте собственные кнопки навигации — используйте нативные контроллы Telegram.
Система событий
Mini App получает события от Telegram через колбэки. Основные архитектурные категории:
| Категория | События | Описание |
|---|---|---|
| Тема | themeChanged | Пользователь сменил тему |
| Viewport | viewportChanged | Размер окна изменился |
| Кнопки | mainButtonClicked, backButtonClicked | Нажатие UI-контроллов |
| Popup | popupClosed | Закрытие диалога |
| QR | qrTextReceived | Результат сканирования QR |
Архитектурный принцип: ваше приложение реагирует на события платформы, а не контролирует их. Telegram остаётся хозяином окружения — Mini App адаптируется.
// Подписка на события (через SDK)
import { on } from '@telegram-apps/sdk-react';
// Viewport
on('viewport_changed', (event) => {
console.log('Новая высота:', event.height);
console.log('Раскрыто на весь экран:', event.is_expanded);
});
Полный пример: тема + контроллы
import { useEffect, useState } from 'react';
import {
init,
miniApp,
mainButton,
backButton,
} from '@telegram-apps/sdk-react';
function App() {
const [screen, setScreen] = useState('main');
useEffect(() => {
init();
miniApp.mount();
miniApp.ready();
backButton.mount();
mainButton.mount();
}, []);
useEffect(() => {
if (screen === 'main') {
backButton.hide();
mainButton.setParams({
text: 'Далее',
isVisible: true,
});
const off = mainButton.onClick(() => setScreen('details'));
return off;
} else {
backButton.show();
mainButton.setParams({ isVisible: false });
const off = backButton.onClick(() => setScreen('main'));
return off;
}
}, [screen]);
return (
<div style={{
backgroundColor: 'var(--tg-theme-bg-color)',
color: 'var(--tg-theme-text-color)',
minHeight: '100vh',
padding: '16px',
}}>
{screen === 'main' ? (
<h1>Главный экран</h1>
) : (
<h1>Детали</h1>
)}
</div>
);
}
Итоги
| Элемент | Назначение | Управление |
|---|---|---|
| CSS-переменные | Адаптация под тему Telegram | Автоматическое обновление при смене темы |
| MainButton | Основное действие (CTA) | text, visibility, loading, click handler |
| BackButton | Навигация назад | visibility, click handler |
| События | Реакция на изменения платформы | Подписка через onEvent / SDK |
В следующем уроке разберём платежи через Telegram Stars — виртуальную валюту для монетизации цифровых товаров.
Частые ошибки
- Хардкодят цвета вместо использования CSS-переменных из Telegram.WebApp.themeParams: приложение не адаптируется к светлой/тёмной теме пользователя.
- Не тестируют приложение в обеих темах (light и dark): баги с контрастом и читаемостью часто проявляются только в одной из тем.
- Игнорируют safe area и bottom insets: контент может перекрываться системными элементами на устройствах с вырезами.
- Используют собственные кнопки навигации вместо BackButton и MainButton от Telegram: это нарушает привычный UX мини-приложений.
Проверка знанийПочему для фона Mini App следует использовать var(--tg-theme-bg-color), а не фиксированный цвет?
Check Your Understanding
Finished the lesson?
Mark it as complete to track your progress
Войдите чтобы оценить урок