Skip to content

Preview Environments

Every pull request gets its own deployment with a unique URL and a dedicated Telegram bot. Preview environments let you test changes in a real Telegram context before merging to production.

Preview deployments are served at:

pr{number}--{project}.tma.sh

For example, pull request #42 on a project called myapp is accessible at:

pr42--myapp.tma.sh

This URL is automatically posted as a comment on the pull request, along with a link to the deployment’s build log.

A preview environment follows the lifecycle of its pull request:

When a pull request is opened (or a new commit is pushed to an existing PR), the GitHub webhook triggers a deployment with type: 'preview'.

PR opened → GitHub webhook → Deployment created (type: preview)

The preview deployment goes through the same build pipeline as production. Framework detection, dependency installation, build execution, and asset upload all work identically.

Each preview environment gets its own Telegram bot with environment: 'preview'. This bot is separate from the production bot, so testing interactions in the preview never affects your live users.

The preview bot’s menu button URL is set to the preview deployment URL (pr{number}--{project}.tma.sh), making it immediately testable in Telegram.

When new commits are pushed to the PR branch, the preview deployment is rebuilt. The URL stays the same (pr{number}--{project}.tma.sh), but it now serves the updated build. The same preview bot is reused.

When the pull request is closed or merged:

  • The KV routing entries for the preview are removed.
  • The preview deployments are marked as cleaned.

There is no Telegram API call to deactivate the preview bot — it simply becomes unreachable because the routing entries no longer exist.

If the PR is merged, the production deployment is triggered separately by the push to the default branch.

Secrets in TMA.sh are scoped by environment. When you create a secret, you choose whether it applies to production, preview, development, or a combination of these.

This is useful for:

  • API keys — Use test/sandbox API keys in preview, production keys in production.
  • Database URLs — Point previews at a staging database.
  • Feature flags — Enable experimental features only in preview.
Project secrets:
DATABASE_URL (production) → postgres://prod-db/myapp
DATABASE_URL (preview) → postgres://staging-db/myapp
STRIPE_KEY (production) → sk_live_...
STRIPE_KEY (preview) → sk_test_...

Preview deployments only receive secrets scoped to preview. They never have access to production secrets.

Share the preview URL and bot with your QA team. They can test the Mini App in a real Telegram environment without affecting production.

Non-technical stakeholders can open the preview bot in Telegram and interact with the app directly. No setup, no local environment, no CLI tools required.

Test different approaches on separate branches. Each PR gets its own isolated environment, so multiple experiments can run in parallel without interference.

Since each preview has its own bot, you can test bot commands, inline queries, and webhook handlers without worrying about conflicts with the production bot’s state.

AspectProductionPreview
URL{project}.tma.shpr{number}--{project}.tma.sh
TriggerPush to default branchPull request opened/updated
BotProduction botDedicated preview bot
SecretsProduction-scopedPreview-scoped
Custom domainsSupportedNot supported
CleanupRetained (last 10)Removed when PR is closed
RollbackSupportedNot applicable

If you don’t need preview environments, you can disable them in project settings. When disabled, pull requests will not trigger deployments. You can re-enable them at any time.