Telegram Mini App локально: Vite, HTTPS и запуск с телефона
Создаём минимальный Telegram Mini App на Vite: публичный HTTPS, allowedHosts, кнопка BotFather, локальный API и проверка ошибок на телефоне.

Telegram Mini App — веб-страница внутри клиента Telegram. Для теста на телефоне локальному серверу нужен доступный извне HTTPS-адрес: localhost на телефоне указывает на сам телефон. Ниже соберём маленькое приложение, откроем его через кнопку бота и проверим изменения без публикации на хостинге.
1. Создайте проект Vite
Понадобятся Node.js, совместимый с устанавливаемой версией Vite, npm и SSH. В новом каталоге выполните:
npm create vite@latest mini-app-demo -- --template vanilla
cd mini-app-demo
npm install
Замените содержимое index.html:
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mini App: локальный тест</title>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
</head>
<body>
<h1>Приложение работает</h1>
<p id="status"></p>
<button id="count" type="button">Нажатий: 0</button>
<script type="module" src="/src/main.js"></script>
</body>
</html>
Замените src/main.js:
const app = window.Telegram?.WebApp;
app?.ready();
document.querySelector('#status').textContent = app?.initData
? 'Получены данные запуска Telegram. Это ещё не авторизация.'
: 'Обычный браузер: откройте приложение через меню бота.';
let count = 0;
const button = document.querySelector('#count');
button.addEventListener('click', () => {
button.textContent = `Нажатий: ${++count}`;
});
Пример не отправляет персональные данные и не требует токена бота в коде страницы.
2. Запустите сервер и получите HTTPS
npm run dev -- --host 127.0.0.1 --port 5173 --strictPort
Откройте http://127.0.0.1:5173 и проверьте кнопку. Во втором терминале на той же машине:
ssh -p 2222 -o ExitOnForwardFailure=yes -R 80:127.0.0.1:5173 tunnelhunt.ru
Скопируйте выданный HTTPS-адрес. Если Vite блокирует обращение с внешним Host, создайте в корне проекта vite.config.js, указав точное имя выданного домена:
import { defineConfig } from 'vite';
export default defineConfig({
server: {
host: '127.0.0.1',
port: 5173,
strictPort: true,
allowedHosts: ['YOUR-SUBDOMAIN.tunnelhunt.ru'],
},
});
Перезапустите Vite. В allowedHosts нужен домен без https:// и пути. Не разрешайте все домены через true. В настройках Vite объясняются ограничения Host, прокси и WebSocket для обновления страницы.
Сначала откройте публичную ссылку в обычном браузере телефона. Если уже здесь ошибка, настройка бота её не исправит.
3. Добавьте кнопку в BotFather
Используйте отдельного тестового бота. Откройте BotFather, отправьте /setmenubutton, выберите бота и задайте HTTPS-адрес приложения и подпись кнопки, например «Открыть тест». Затем откройте личный чат с ботом, нажмите Start, если ещё не начинали диалог, и кнопку меню приложения.
Этот способ запуска описан в документации Telegram Mini Apps. Для показа такой страницы не требуется настраивать webhook бота: это отдельный механизм приёма сообщений.
Нажмите кнопку счётчика. Теперь поменяйте заголовок в index.html. Если автоматическое обновление не сработало, закройте Mini App и откройте снова. WebSocket для HMR требует отдельной проверки всей цепочки прокси; обычная загрузка страницы может работать и без него.
4. Как обращаться к локальному API
Запрос страницы к http://localhost:3000/api будет обращаться к телефону, а HTTPS-страница также может заблокировать HTTP-запрос как mixed content. Удобнее использовать относительный адрес /api и прокси Vite.
Если ваш локальный backend уже обслуживает /api на порту 3000, добавьте внутрь server:
proxy: {
'/api': 'http://127.0.0.1:3000',
},
Тогда fetch('/api/health') из страницы пройдёт через тот же публичный домен. Путь /api/health должен существовать в вашем backend; Vite сам его не создаёт.
Прокси открывает эти маршруты внешним посетителям. Для личного кабинета отправляйте Telegram.WebApp.initData своему backend и проверяйте подпись и срок действия на сервере по алгоритму Telegram. Наличие строки и содержимое initDataUnsafe не подтверждают личность. Токен бота хранится только на сервере; в переменные VITE_* его помещать нельзя.
Диагностика
| Симптом | Проверка |
|---|---|
Blocked request. This host is not allowed |
Добавьте текущий домен в allowedHosts и перезапустите Vite |
Публичный URL возвращает 502 |
Проверьте сервер на 5173 и SSH-соединение |
| Страница открывается, API не отвечает | Проверьте относительный путь и локальный backend |
Пустой initData в браузере |
Откройте через кнопку меню внутри Telegram |
| После перезапуска ссылка сломалась | Обновите домен в BotFather и Vite, если он изменился |
Для повторяемых тестов удобен резервируемый субдомен. Dev-сервер предназначен для разработки: после проверки остановите туннель через Ctrl+C. Для обработки сообщений бота отдельно используйте гайд по Telegram webhook.
Готовы запустить свой первый туннель?
Начните использовать TunnelHunt бесплатно уже сегодня и откройте доступ к локальному серверу всего одной командой.
Зарегистрироваться бесплатно →По теме

Telegram-бот локально: webhook, secret_token и отладка на localhost
5 июня 2025 г.
Запустите Telegram-бота на localhost: выберите polling или webhook, настройте HTTPS и secret_token, проверьте getWebhookInfo и исправьте ошибки доставки.

TunnelHunt + React/Vue/Angular: Полное руководство по локальной разработке
3 сентября 2025 г.
Настройка туннелей для популярных frontend фреймворков. Hot reload, CORS, production сборки и лучшие практики для React, Vue и Angular разработчиков.

Как открыть localhost в интернете: публичный HTTPS через SSH
11 сентября 2026 г.
Пошагово открываем локальный сайт из интернета без настройки роутера: SSH-туннель, проверка ссылки, Docker, Vite и диагностика ошибок.

Разработка мобильного приложения с локальным бэкендом: простое решение с TunnelHunt
15 мая 2025 г.
Как подключить ваше мобильное приложение, работающее на реальном устройстве, к API, запущенному на localhost? Узнайте, как TunnelHunt решает эту проблему за одну минуту.