-
-
Notifications
You must be signed in to change notification settings - Fork 0
2. Installation & Setup
This guide walks you through setting up your first Telegram Mini App with telegram-webapp-sdk.
Before starting, ensure you have:
-
Rust Toolchain (1.90 or later)
# Check your version rustc --version # If you need to install/update curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
Telegram Bot
- Create one via @BotFather
- Send
/newbotand follow instructions - Save your bot token (looks like
110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw)
-
Basic Rust Knowledge
- Understanding of Cargo projects
- Familiarity with either Yew or Leptos (recommended)
# Create a new Rust project
cargo new my-telegram-app
cd my-telegram-appEdit Cargo.toml:
[package]
name = "my-telegram-app"
version = "0.1.0"
edition = "2021"
[dependencies]
# Core SDK with macros
telegram-webapp-sdk = { version = "0.3", features = ["yew", "macros"] }
# Yew framework
yew = { version = "0.21", features = ["csr"] }For Leptos instead of Yew:
[dependencies]
telegram-webapp-sdk = { version = "0.3", features = ["leptos", "macros"] }
leptos = { version = "0.8", features = ["csr"] }Create index.html in your project root:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>My Telegram App</title>
<!-- REQUIRED: Telegram WebApp script -->
<script src="https://telegram.org/js/telegram-web-app.js"></script>
</head>
<body></body>
</html>Important: The Telegram script must be loaded before your WASM bundle.
Edit src/main.rs:
use telegram_webapp_sdk::{telegram_app, telegram_page, telegram_router, TelegramWebApp};
use yew::prelude::*;
#[telegram_page(path = "/")]
#[function_component(Home)]
fn home() -> Html {
let webapp = TelegramWebApp::new();
// Get user info from Telegram
let user_name = webapp
.init_data_unsafe()
.user
.as_ref()
.map(|u| u.first_name.clone())
.unwrap_or_else(|| "Guest".to_string());
html! {
<div>
<h1>{ format!("Hello, {}!", user_name) }</h1>
<p>{ "Welcome to your first Telegram WebApp!" }</p>
<button onclick={Callback::from(move |_| {
webapp.show_alert("Button clicked!");
})}>
{ "Click Me" }
</button>
</div>
}
}
#[telegram_app(auto_init)]
#[function_component(App)]
fn app() -> Html {
telegram_router! {
"/" => Home,
}
}
fn main() {
yew::Renderer::<App>::new().render();
}use telegram_webapp_sdk::{provide_telegram_context, TelegramWebApp};
use leptos::prelude::*;
#[component]
fn App() -> impl IntoView {
// Provide Telegram context to child components
provide_telegram_context();
let webapp = TelegramWebApp::new();
let user_name = move || {
webapp
.init_data_unsafe()
.user
.as_ref()
.map(|u| u.first_name.clone())
.unwrap_or_else(|| "Guest".to_string())
};
view! {
<div>
<h1>"Hello, " {user_name} "!"</h1>
<p>"Welcome to your first Telegram WebApp!"</p>
<button on:click=move |_| {
webapp.show_alert("Button clicked!");
}>
"Click Me"
</button>
</div>
}
}
fn main() {
console_error_panic_hook::set_once();
mount_to_body(|| view! { <App /> })
}Trunk is the recommended build tool for Rust WASM apps:
cargo install trunk# Development server (with hot reload)
trunk serve
# Production build
trunk build --releaseYour app will be at http://localhost:8080 (development) or in dist/ folder (production).
For development without Telegram, enable the mock feature:
[dependencies]
telegram-webapp-sdk = { version = "0.3", features = ["yew", "macros", "mock"] }Then initialize the mock:
#[cfg(feature = "mock")]
use telegram_webapp_sdk::mock::{init_mock, MockConfig, MockUser};
#[cfg(feature = "mock")]
fn setup_mock() {
init_mock(MockConfig {
user: Some(MockUser {
id: 12345,
first_name: "Test User".into(),
username: Some("testuser".into()),
..Default::default()
}),
platform: "ios",
version: "7.0",
..Default::default()
});
}Telegram requires HTTPS. Use a tunnel to test with real Telegram:
# Install cloudflared
# https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/
# Terminal 1: Run your app
trunk serve
# Terminal 2: Create tunnel
cloudflared tunnel --url http://localhost:8080You'll get a URL like https://random-name.trycloudflare.com.
# Install ngrok
# https://ngrok.com/download
# Terminal 1: Run your app
trunk serve
# Terminal 2: Create tunnel
ngrok http 8080You'll get a URL like https://abc123.ngrok.io.
Note: Tunnel URLs change on each restart. Update BotFather after restarting.
- Open @BotFather
- Send
/mybots - Select your bot
- Choose "Bot Settings" → "Menu Button"
- Choose "Configure menu button"
- Send "Edit menu button URL"
- Enter your WebApp URL:
- Development:
https://your-tunnel-url.trycloudflare.com - Production:
https://your-domain.com/index.html
- Development:
- Open your bot in Telegram
- Click the menu button (bottom-left, next to message input)
- Your WebApp should open inside Telegram
After setup, your project should look like:
my-telegram-app/
├── Cargo.toml # Dependencies
├── index.html # HTML template with Telegram script
├── src/
│ └── main.rs # Your app code
└── dist/ # Build output (after trunk build)
├── index.html
├── my-telegram-app-xxxxx.wasm
└── my-telegram-app-xxxxx.js
Enable optional features in Cargo.toml:
[dependencies]
telegram-webapp-sdk = {
version = "0.3",
features = [
"yew", # Yew integration
"leptos", # Leptos integration (alternative to yew)
"macros", # Macros for routing and initialization
"mock", # Mock environment for testing
]
}Feature descriptions:
-
yew- Yew framework integration (hooks, components) -
leptos- Leptos framework integration (signals, components) -
macros- Declarative macros (telegram_app!,telegram_page!, etc.) -
mock- Mock Telegram environment for local testing
Create Trunk.toml in your project root:
[[hooks]]
stage = "build"
command = "sh"
command_arguments = ["-c", "wasm-opt -Oz -o dist/my-telegram-app_bg.wasm dist/my-telegram-app_bg.wasm"]This requires wasm-opt to be installed:
# On macOS
brew install binaryen
# On Ubuntu/Debian
apt-get install binaryen
# On Windows (via scoop)
scoop install binaryenFor deployment to a subdirectory:
trunk build --release --public-url "https://your-domain.com/app/"This ensures all assets load from the correct path.
Symptom: Console error: Telegram is not defined
Solution: Ensure index.html loads the Telegram script:
<script src="https://telegram.org/js/telegram-web-app.js"></script>This must be in <head> before your WASM bundle loads.
Symptom:
it looks like the Rust project used to create this Wasm file was linked against
version of wasm-bindgen that uses a different bindgen format than this binary:
rust Wasm file schema version: 0.2.93
this binary schema version: 0.2.92
Solution:
Option 1 - Install matching version:
cargo install wasm-bindgen-cli --version 0.2.93Option 2 - Update dependencies:
cargo update
trunk build --releaseSymptom: WASM bundle is several MB
Solutions:
-
Enable release mode:
trunk build --release
-
Optimize with wasm-opt (see "Optimizing Build Size" above)
-
Add to
Cargo.toml:[profile.release] opt-level = "z" # Optimize for size lto = true # Link-time optimization codegen-units = 1 # Better optimization
Checklist:
- URL is HTTPS (not HTTP)
- URL is publicly accessible (not
localhost) - URL is configured in BotFather
- Telegram script is loaded in
index.html - No console errors in browser DevTools
Debug in Telegram Desktop:
- Open Telegram Desktop
- Enable Debug Menu: Settings → Advanced → Experimental → Enable WebView Inspecting
- Right-click WebApp → "Inspect"
- Check console for errors
Symptom: Compilation errors mentioning unstable features
Solution: Update Rust to 1.90+:
rustup update stable
rustc --version # Should be 1.90 or laterNow that your project is set up, learn about the core concepts: