Веб

Как обновить Telegram Web App без кеша — надёжные способы

Простые и надежные способы очистки кэша Telegram Web App: версионирование URL, хеширование файлов, Cache-Control, CDN-инвалидация и in-app проверка версий.

Как очистить кэш мини‑приложения Telegram (Web App), чтобы пользователи сразу получали обновлённую HTML/JS‑версию без ручного «⋮ → Обновить страницу»? У меня мини‑приложение на HTML+JS, запускаемое через бота: после изменения HTML Telegram продолжает загружать старую версию из кэша и пользователи получают ошибки, пока не обновят страницу вручную. Можно ли принудительно сбросить кэш или указать новую версию приложения (например, в BotFather или в настройках Web App)? Какие надёжные методы cache‑busting и деплоя подходят для Telegram mini apps (изменение URL/параметров, заголовки кеширования, Service Worker, мета‑теги и т.п.)?

Самый надёжный способ заставить Telegram web app сразу показывать обновлённую HTML/JS‑версию — версионировать URL и имена файлов. Мини‑приложения Telegram кешируются по URL (telegram кэш), поэтому добавление уникального параметра (?v=123 или ?t=Date.now()) или включение хешей в имена JS/CSS — рабочий cache‑busting. HTTP‑заголовки, мета‑теги и Service Worker можно использовать дополнительно, но Telegram клиенты порой их игнорируют, а в BotFather нет прямой настройки для «сброса кэша».


Содержание


Как Telegram web app кеширует мини‑приложения

Telegram кеширует содержимое Web App по URL — то есть всякая уникальная ссылка считается «новой» и загружается заново, а одинаковая ссылка отдаётся из кэша клиента/прокси. Это подтверждают обсуждения разработчиков: в одном из Q&A на Habr прямо указывают, что Telegram кэширует контент по URL и что «изменение URL» заставляет Telegram загрузить новую версию (см. обсуждение) — https://qna.habr.com/q/1360110.

Ещё нюанс: не всегда кеш контролируется только серверными заголовками. В некоторых клиентах (особенно десктопных) встречались случаи, когда initData или другие элементы хранились локально дольше, чем вы ожидаете — пример: проблема с кешированием initData в telegram‑desktop (обсуждение на GitHub) — https://github.com/telegramdesktop/tdesktop/issues/28303.

Что это даёт вам на практике? Простая логика: если вы хотите гарантированно доставить новую сборку — меняйте URL (или добавляйте параметр), а не надеетесь, что Telegram сразу заберёт свежую версию по старому адресу.


Надёжные методы cache‑busting для мини‑приложений Telegram web app

Вот рабочие, практические приёмы, которые реально используются.

  1. Версионирование URL (самое простое и надёжное)
  • При деплое добавляйте к корню приложения параметр версии: https://myapp.example.com/?v=20260104 или ?t=1672531200000. Телеграм считает URL новым и загрузит файл заново. Пример в JS:
js
const url = `https://myapp.example.com/?v=${BUILD_VERSION}`;
window.open(url); // или вставляете в кнопку web_app
  • Если вы генерируете ссылку динамически (например, в InlineKeyboardButton.web_app), вставляйте параметр версии туда — это не требует изменения настроек BotFather.
  1. Хеширование имён статических файлов (best practice для любых SPA)
  • Генерируйте сборку с content‑hash в имени: app.3a1f2b.js, style.8c9d0e.css. После изменения контента имя меняется — браузер и CDN загрузят новый файл.
  • Для index.html лучше либо менять сам URL, либо выставлять для него короткий TTL / no‑cache, а для хешированных ассетов — долгий TTL.
  1. Комбинация «короткий TTL для index + долгий TTL для хешированных ассетов»
  • Настройте сервер/CDN: index.html — Cache-Control: no-store, must-revalidate (или короткий max-age=60), а ассеты — Cache-Control: public, max-age=31536000, immutable. Так вы быстро обновляете ссылку на новые ассеты, но сами ассеты максимально кэшируются.
  1. Инвалидация CDN / Purge
  • Если вы используете CDN (Cloudflare, Fastly, S3+CloudFront), делайте автоматический purge или версионирование URL — быстрее и надёжнее, чем надеяться на клиентский сброс.
  1. «Мягкое» обновление внутри приложения (in‑app version check)
  • Делаете небольшой endpoint /version.json (или встраиваете переменную в HTML) и периодически (или сразу при загрузке) проверяете версию. Если обнаружена новая — показываете пользователю баннер «Доступна новая версия — обновить» или автоматически перенаправляете на URL с параметром версии. Пример:
js
fetch('/version.json', {cache: 'no-store'})
 .then(r => r.json())
 .then(data => {
 if (data.version !== BUILD_VERSION) {
 // безопасный способ — предложить обновить
 if (confirm('Доступна новая версия приложения. Обновить сейчас?')) {
 location.href = location.pathname + '?v=' + data.version;
 }
 }
 });
  • Такой подход витально важен, если вы не можете мгновенно контролировать кэш клиента.
  1. Использование уникального базового URL при критическом откате
  • При форс‑мажоре (например, приложение ломается в проде) просто разошлите пользователям ссылку с другим параметром/поддоменом — это мгновенно гарантирует загрузку новой версии.

HTTP‑заголовки, ETag и почему Telegram может их игнорировать

Хорошая серверная конфигурация всё ещё полезна, но не панацея.

Рекомендуемые заголовки:

  • Для index.html (или URL, используемого для открытия Web App):
    Cache-Control: no-store, must-revalidate, no-cache
    Pragma: no-cache
    Expires: 0
  • Для хешированных статических файлов:
    Cache-Control: public, max-age=31536000, immutable
  • Можно отдавать ETag и Last‑Modified — это стандартный механизм условной загрузки.

Пример конфигурации для Nginx:

nginx
location = /index.html {
 add_header Cache-Control "no-store, must-revalidate, no-cache";
 add_header Pragma "no-cache";
 add_header Expires "0";
}
location /static/ {
 add_header Cache-Control "public, max-age=31536000, immutable";
}

Почему этого может оказаться недостаточно? В документации и руководствах TMA/дружественных проектов указывается, что даже при явных заголовках клиенты/прокси могут кешировать копии, и иногда проще поменять URL, чем рассчитывать на немедленную реакцию клиента — см. рекомендации по кэшу и заголовкам в примечаниях TMA — https://docs.ton.org/v3/guidelines/dapps/tma/guidelines/tips-and-tricks.


Service Worker, мета‑теги и методы, которых лучше избегать

  • Service Worker: в контексте Telegram Web App его поведение ненадёжно — некоторые Web App‑окружения (и встроенные браузеры Telegram) либо не поддерживают SW, либо их реализация отличается. В обсуждении на Habr отмечали, что Service Worker в Web‑App пока не поддерживается/не рекомендуется. Использовать SW для «мгновенного обновления» — рискованно. См. https://qna.habr.com/q/1360110.
  • Мета‑теги типа <meta http-equiv="cache-control" content="no-cache"> часто игнорируются браузерами/прокси и не заменяют корректные HTTP‑заголовки.
  • Не пытайтесь «почистить кэш» через BotFather — такой кнопки нет. Меняйте URL/версию.

Коротко: SW и meta‑теги не дают гарантии в встроенных клиентах Telegram, лучше комбинировать URL‑версионирование и заголовки.


Рекомендованный workflow деплоя для мини‑приложения (шаг‑за‑шаг)

  1. CI/CD: собирайте билд с content‑hash в именах ассетов (webpack/vite/parcel).
  2. Устанавливайте BUILD_VERSION (дату, номер билда, git‑hash). Вставляйте в /version.json и в HTML переменные.
  3. Деплойте ассеты на CDN/сервер: ассеты — с долгим TTL; index — с коротким TTL или no-store.
  4. После деплоя: либо делаете CDN purge для index, либо обновляете ссылку, которую бот использует для открытия Web App (добавляя ?v=BUILD_VERSION). Менять URL — самый быстрый способ обеспечить обновление у всех пользователей.
  5. В приложении: при старой версии показывайте пользователю сообщение и предлагайте перезагрузить или автоматически перенаправляйте с новым ?v=.
  6. Мониторинг: следите за ошибками (Sentry, логи) и будьте готовы срочно разослать новую ссылку с уникальным параметром.

Пример простой команды для добавления версии в ссылку (Node):

js
const launchUrl = (base, version) => `${base}?v=${version}`;

Отладка и экстренные меры для обновления у пользователей

  • Если часть пользователей видит старую версию — разошлите им ссылку с новым параметром ?v=; откройте приложение через новую ссылку — это надёжно.
  • Если проблема связана с кешированием initData (авторизация/сессии), имейте на сервере механизм обмена initData на краткоживущие токены; а также учитывайте, что некоторые клиенты кешируют initData дольше — см. обсуждение на GitHub — https://github.com/telegramdesktop/tdesktop/issues/28303.
  • Для обновления предпросмотров ссылок (preview) Telegram предлагает отдельные инструменты (например, @WebpageBot) — это про превью, не про Web App, но пригодится, если ломаются карточки ссылок — https://ru.stackoverflow.com/questions/557077/Как-почистить-кэш-шаринга-ссылок-в-Telegram.
  • В самом крайнем случае (отсутствует другая возможность) разработчики отмечают, что переустановка клиента может очистить проблемный кэш — неудобно, но документировано как рабочий способ — https://docs.ton.org/v3/guidelines/dapps/tma/guidelines/tips-and-tricks.
  • Проактивно: прежде чем менять критический код, откатывайте/режьте фичи и готовьте «фоллбек» на старую версию (версии и флаги), чтобы избежать массового падения.

Источники

  1. Обсуждение кеширования и практические советы по cache‑busting на Habr Q&A: https://qna.habr.com/q/1360110
  2. Рекомендации по заголовкам и отключению кеша (руководство TMA): https://docs.ton.org/v3/guidelines/dapps/tma/guidelines/tips-and-tricks
  3. Пример проблемы с кешированием initData в telegram‑desktop (issue): https://github.com/telegramdesktop/tdesktop/issues/28303
  4. Вопрос про очистку кеша превью ссылок в Telegram (StackOverflow RU): https://ru.stackoverflow.com/questions/557077/Как-почистить-кэш-шаринга-ссылок-в-Telegram
  5. Отчёт об ошибках и проблемах с очисткой кэша в клиентах Telegram: https://bugs.telegram.org/c/44945

Заключение

Кратко: для надежного обновления мини‑приложения используйте версионирование URL и хеширование имён файлов — это рабочая практика против telegram кэш. HTTP‑заголовки, CDN‑инвалидация и in‑app проверка версии усиливают защиту, а Service Worker/мета‑теги не дают гарантии в Web App. И да: в BotFather нет «кнопки» для сброса кэша — меняйте URL и стройте простой механизм ver‑check в приложении, чтобы пользователи получали свежую сборку сразу.

Авторы
Проверено модерацией
Модерация