Если вы когда-нибудь пытались разобраться с @telegram-apps/sdk-react по официальной документации — вы знаете, как это
бывает. Половина примеров устарела, TypeScript ругается на типы, а в чате поддержки советуют «почитать исходники».
Эта статья — то, что хотелось бы иметь при первом знакомстве с SDK. Разбираем всё по порядку: установка, инициализация, работа с UI-компонентами Telegram, получение данных пользователя и типичные ошибки, которые встречаются почти в каждом проекте.
Что такое @telegram-apps/sdk-react и зачем он нужен
Telegram Mini Apps работают через WebApp API — набор методов, которые Telegram встраивает в JavaScript-окружение
браузера. Напрямую работать с window.Telegram.WebApp можно, но неудобно: нет типов, нет реактивности, код быстро
превращается в кашу.
@telegram-apps/sdk-react — это обёртка над WebApp API с React-хуками, TypeScript-типами и удобными компонентами. Он
берёт на себя инициализацию и даёт вам чистый декларативный интерфейс.
Основные возможности:
- Хуки для работы с MainButton, BackButton, SettingsButton
- Реактивный доступ к данным пользователя (initDataUnsafe)
- Управление Viewport и цветовой схемой
- Работа с CloudStorage
- Поддержка платежей через Invoice
Установка и настройка проекта
Создаём проект. Рекомендуется Vite + React + TypeScript:
npm create vite@latest my-mini-app -- --template react-ts
cd my-mini-app
npm install
Устанавливаем SDK:
npm install @telegram-apps/sdk-react @telegram-apps/sdk
Для разработки без Telegram-клиента понадобится эмулятор:
npm install -D @telegram-apps/telegram-mock
Структура проекта после установки:
src/
├── components/
├── hooks/
├── App.tsx
├── main.tsx
└── mockEnv.ts # для разработки
Инициализация SDK
Это первое, что нужно сделать до любого использования хуков. Инициализация должна произойти до монтирования React-дерева.
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import {init, isTMA} from '@telegram-apps/sdk-react';
import App from './App';
async function bootstrap() {
// В dev-режиме эмулируем окружение Telegram
if (import.meta.env.DEV) {
const {mockTelegramEnv, parseInitData} = await import('@telegram-apps/telegram-mock');
mockTelegramEnv({
themeParams: {
accentTextColor: '#6ab2f2',
bgColor: '#17212b',
buttonColor: '#5288c1',
buttonTextColor: '#ffffff',
headerBgColor: '#17212b',
hintColor: '#708499',
linkColor: '#6ab3f3',
secondaryBgColor: '#232e3c',
sectionBgColor: '#17212b',
sectionHeaderTextColor: '#6ab3f3',
subtitleTextColor: '#708499',
textColor: '#f5f5f5',
},
initDataRaw: new URLSearchParams([
['user', JSON.stringify({
id: 123456789,
first_name: 'Иван',
last_name: 'Петров',
username: 'ivan_petrov',
language_code: 'ru',
})],
['hash', 'test_hash'],
]).toString(),
});
}
// Проверяем, что мы внутри Telegram
if (isTMA('simple')) {
await init();
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App/>
</React.StrictMode>
);
}
bootstrap();
Важный момент: init() — асинхронная функция. Не вызывайте хуки SDK до её завершения, иначе получите ошибку
SDK is not initialized.
SDKProvider — оборачиваем приложение
// src/App.tsx
import {SDKProvider} from '@telegram-apps/sdk-react';
import {MainScreen} from './components/MainScreen';
export default function App() {
return (
<SDKProvider acceptCustomStyles debug={import.meta.env.DEV}>
<MainScreen/>
</SDKProvider>
);
}
acceptCustomStyles — позволяет Telegram применять свои CSS-переменные для темизации. Рекомендуется включать всегда.
Получение данных пользователя: initDataUnsafe
Это самый частый вопрос в поиске — initDataUnsafe @telegram-apps/sdk. Разбираем подробно.
import {useInitData} from '@telegram-apps/sdk-react';
function UserProfile() {
const initData = useInitData();
if (!initData) {
return <div>Загрузка...</div>;
}
const {user} = initData;
if (!user) {
return <div>Пользователь не определён</div>;
}
return (
<div>
<p>Имя: {user.firstName} {user.lastName}</p>
<p>Username: @{user.username}</p>
<p>ID: {user.id}</p>
<p>Язык: {user.languageCode}</p>
</div>
);
}
Почему "Unsafe"? Потому что данные из initDataUnsafe не верифицированы на клиенте. Для продакшена обязательно
проверяйте initData.hash на бэкенде:
# Пример верификации на Python (бэкенд)
import hashlib
import hmac
def verify_init_data(init_data: str, bot_token: str) -> bool:
parsed = dict(item.split('=', 1) for item in init_data.split('&'))
received_hash = parsed.pop('hash', '')
data_check_string = '\n'.join(
f'{k}={v}' for k, v in sorted(parsed.items())
)
secret_key = hmac.new(
b'WebAppData',
bot_token.encode(),
hashlib.sha256
).digest()
expected_hash = hmac.new(
secret_key,
data_check_string.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(received_hash, expected_hash)




