Если вы когда-нибудь пытались разобраться с @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)




