The development of Telegram Mini App opens up new opportunities for creating fully functional web applications right inside Telegram. For React developers, there are several approaches to integrating with the Telegram WebApp API. We will look at the most effective way using the @twa-dev/sdk library, and also pay special attention to critical security aspects, such as initData validation on the backend.
Using @twa-dev/sdk for React
The @twa-dev/sdk library significantly simplifies interaction with the Telegram WebApp API by providing convenient React hooks and components. It abstracts the low-level details of working with window.Telegram.WebApp, making development more pleasant and less error-prone.
To get started, install the library:
npm install @twa-dev/sdkAfter installation, you can use hooks to access the WebApp object and its methods. For example, to get initDataUnsafe and configure the MainButton:
import React, { useEffect } from 'react';
import { useWebApp, useInitData, useMainButton } from '@twa-dev/sdk/react';
function App() {
const webApp = useWebApp();
const initData = useInitData();
const mainButton = useMainButton();
useEffect(() => {
if (webApp) {
webApp.ready();
webApp.expand(); // Расширяем Mini App на весь экран
}
}, [webApp]);
useEffect(() => {
if (mainButton) {
mainButton.setText('Отправить данные');
mainButton.onClick(() => {
// Обработка клика по MainButton
console.log('MainButton clicked!');
webApp.showAlert('Данные отправлены!');
// Здесь можно отправить initData на ваш бэкенд
});
mainButton.show();
mainButton.enable();
}
}, [mainButton, webApp]);
return (
<div>
<h1>Добро пожаловать в Mini App!</h1>
<p>Ваши данные: {initData ? initData.user?.first_name : 'Загрузка...'}</p>
<button onClick={() => webApp.showAlert('Привет от кнопки!')}>Показать Alert</button>
</div>
);
}
export default App;
useWebApp() provides access to the window.Telegram.WebApp object, useInitData() provides access to the parsed initDataUnsafe data, and useMainButton() allows you to control the main button in the Mini App interface.
Backend validation of initData
A key security aspect of any Telegram Mini App is the validation of initData. This data contains information about the user, bot, and session, and its authenticity must be verified on your backend. Telegram Bot API generates a hash based on all initData parameters and the bot's secret key. You must recalculate this hash on your side and compare it with the one received from the client.
Here is an example of implementing initData validation in PHP:
<?php
/**
* Валидация initData из Telegram Mini App.
* @param string $initDataString Строка initData, полученная от клиента.
* @param string $botToken Токен вашего Telegram бота.
* @return array|false Ассоциативный массив с данными, если валидация успешна, иначе false.
*/
function validateTelegramInitData(string $initDataString, string $botToken): array|false
{
$data = [];
parse_str($initDataString, $data);
if (!isset($data['hash'])) {
return false;
}
$hash = $data['hash'];
unset($data['hash']);
// Сортируем данные по ключам и формируем строку для проверки
ksort($data);
$checkString = [];
foreach ($data as $key => $value) {
$checkString[] = $key . '=' . $value;
}
$checkString = implode("\n", $checkString);
// Вычисляем секретный ключ
$secretKey = hash_hmac('sha256', $botToken, 'WebAppData', true);
// Вычисляем HMAC-SHA256 хеш
$calculatedHash = hash_hmac('sha256', $checkString, $secretKey);
// Сравниваем хеши
// Используем timing-safe сравнение для предотвращения атак по времени
if (hash_equals($calculatedHash, $hash)) {
// Проверяем срок действия auth_date (опционально, но рекомендуется)
// По умолчанию Telegram устанавливает auth_date со сроком жизни 24 часа.
// Можно задать свой лимит, например, 1 час.
if (isset($data['auth_date']) && (time() - (int)$data['auth_date']) > 3600) { // 1 час
// echo "Warning: initData is too old.\n";
// return false; // или обрабатываем как устаревшие данные
}
return $data;
}
return false;
}
// Пример использования:
$initDataFromClient = getenv('TELEGRAM_INIT_DATA'); // Из заголовка, POST-параметра и т.п.
$botToken = getenv('TELEGRAM_BOT_TOKEN');
if (!$initDataFromClient || !$botToken) {
die("Environment variables TELEGRAM_INIT_DATA and TELEGRAM_BOT_TOKEN must be set.\n");
}
$validatedData = validateTelegramInitData($initDataFromClient, $botToken);
if ($validatedData) {
echo "InitData успешно валидирована!\n";
// print_r($validatedData);
// Теперь можно безопасно использовать данные пользователя, например: $validatedData['user']
} else {
echo "Ошибка валидации InitData.\n";
// Логируем попытку невалидного доступа
}
?>
It is important to remember that initDataUnsafe on the frontend contains data that has not yet been validated. Always send the full initData string to your backend and perform validation there. Only after successful validation can you trust this data.
MainButton: The Main Button of the Mini App
MainButton is a special button located at the bottom of the Mini App, which is part of the Telegram interface rather than your web application. It is designed to perform primary actions, such as submitting a form, confirming an order, etc. It is controlled via the WebApp API.
mainButton.setText(text): Sets the button text.mainButton.show(): Shows the button.mainButton.hide(): Hides the button.mainButton.enable(): Enables the button (makes it clickable).mainButton.disable(): Disables the button (makes it unclickable).mainButton.showProgress(leaveActive): Shows a loading indicator.leaveActive(boolean) — iftrue, the button will remain active while showing progress.mainButton.hideProgress(): Hides the loading indicator.mainButton.onClick(callback): Adds a click handler.
Proper use of the MainButton improves the user experience, as the button is located in a place familiar to the user and does not clutter your application's interface.
Mini App Lifecycle and Useful Methods
A Mini App has its own lifecycle and a set of methods for interacting with the Telegram client:
webApp.ready(): A mandatory call that tells Telegram that your application is loaded and ready to work.webApp.expand()/webApp.viewportStable(): Expands the Mini App to full screen.viewportStableis called when the viewport size stabilizes.webApp.close(): Closes the Mini App.webApp.showAlert(message): Shows a native Telegram alert.webApp.showConfirm(message, callback): Shows a native Telegram confirm dialog.webApp.showPopup(params, callback): Shows a customizable popup.webApp.openLink(url): Opens a link in an external browser.webApp.openTelegramLink(url): Opens a link inside the Telegram app (for example,t.me/bot_name).
Errors and Limits
When developing a Mini App, it is important to consider potential errors and limits:
- Mini App Size: Although Telegram does not impose strict limits on the size of downloaded content, excessively large applications will load slowly, which will negatively affect the UX. Optimize bundles and use lazy loading.
- API Access: Some WebApp API methods may be unavailable in older versions of Telegram clients. Always check for the existence of methods before using them (for example,
if (webApp.isVersionAtLeast('6.1'))). initDataSecurity: As mentioned earlier, do not trustinitDataUnsafedata without validation on the backend.- Network Requests: A Mini App works like a regular web application, so all network requests to your backend must be secure (HTTPS) and handle potential network errors.
Developing a Mini App on React using @twa-dev/sdk provides a powerful toolkit for creating interactive and secure applications inside Telegram. Do not forget about data validation on the backend and test your application on different devices and versions of the Telegram client.
If you are looking for ready-made solutions or help with developing Telegram bots and Mini Apps, visit BotCreator.