Skip to content

8. Production Guide

RAprogramm edited this page Nov 4, 2025 · 1 revision

Chapter 8: Production Guide

Deploy your Telegram Mini App to production.

Build Configuration

Cargo.toml Optimizations

[profile.release]
opt-level = "z"          # Optimize for size
lto = true               # Link-time optimization
codegen-units = 1        # Better optimization
strip = true             # Strip symbols
panic = "abort"          # Smaller binary

Trunk.toml

[[hooks]]
stage = "build"
command = "sh"
command_arguments = ["-c", "wasm-opt -Oz -o dist/app_bg.wasm dist/app_bg.wasm"]

[build]
public_url = "https://your-domain.com/app/"

Deployment Options

Static Hosting (Recommended)

GitHub Pages

# Build
trunk build --release

# Deploy
cd dist
git init
git add -A
git commit -m "Deploy"
git push -f git@github.com:username/repo.git master:gh-pages

Vercel

# Install Vercel CLI
npm i -g vercel

# Build
trunk build --release

# Deploy
vercel --prod dist/

Cloudflare Pages

# Build
trunk build --release

# Configure in Cloudflare dashboard:
# Build command: trunk build --release
# Build output directory: dist

Server-Side Validation

NEVER validate init data on client. Use server:

// Backend (using init-data-rs)
use init_data_rs::{validate, InitData};
use axum::{Json, extract::State};

async fn authenticate(
    State(bot_token): State<String>,
    Json(payload): Json<AuthRequest>,
) -> Result<Json<AuthResponse>, AppError> {
    // Validate signature and expiration
    let init_data: InitData = validate(
        &payload.init_data,
        &bot_token,
        Some(3600) // 1 hour expiration
    )?;

    // Create session
    let token = create_session(&init_data.user)?;

    Ok(Json(AuthResponse { token }))
}

Security Checklist

  • Use HTTPS everywhere
  • Validate init_data on backend
  • Never expose bot tokens in client
  • Set CSP headers:
    <meta http-equiv="Content-Security-Policy"
          content="script-src 'self' https://telegram.org">
  • Rate limit API endpoints
  • Sanitize user input
  • Use secure storage for sensitive data

Performance

Lazy Loading

use yew::suspense::{Suspense, SuspenseProps};

html! {
    <Suspense fallback={html! { <div>{ "Loading..." }</div> }}>
        <HeavyComponent />
    </Suspense>
}

Code Splitting

Split large apps into smaller chunks:

[profile.release]
codegen-units = 16  # Allow parallel code generation

Next: Chapter 9 - Testing

Clone this wiki locally