Skip to content

7. Common Patterns

RAprogramm edited this page Nov 4, 2025 · 1 revision

Chapter 7: Common Patterns

Real-world examples and best practices.

Order/Purchase Flow

Complete e-commerce pattern:

use telegram_webapp_sdk::{TelegramWebApp, api::cloud_storage};
use yew::prelude::*;

#[function_component(ProductPage)]
fn product_page() -> Html {
    let webapp = TelegramWebApp::new();
    let (quantity, set_quantity) = use_state(|| 1);

    let add_to_cart = {
        let webapp = webapp.clone();
        let quantity = *quantity;
        Callback::from(move |_| {
            // Save to cloud storage
            cloud_storage::set_item(
                "cart",
                &format!("{{\"quantity\": {}}}", quantity),
                |success| {
                    if success {
                        webapp.show_alert("Added to cart!");
                    }
                }
            );
        })
    };

    html! {
        <>
            <h1>{ "Product" }</h1>
            <button onclick={add_to_cart}>{ "Add to Cart" }</button>
        </>
    }
}

Form with Validation

use telegram_webapp_sdk::TelegramWebApp;
use yew::prelude::*;

#[function_component(Form)]
fn form() -> Html {
    let webapp = TelegramWebApp::new();
    let (name, set_name) = use_state(String::new);
    let (email, set_email) = use_state(String::new);

    let submit = {
        let webapp = webapp.clone();
        let name = (*name).clone();
        let email = (*email).clone();
        
        Callback::from(move |_| {
            if name.is_empty() || email.is_empty() {
                webapp.show_alert("Please fill all fields");
                return;
            }

            // Submit to backend
            webapp.show_confirm("Submit form?", move |confirmed| {
                if confirmed {
                    // Send data
                }
            });
        })
    };

    html! {
        <>
            <input
                type="text"
                placeholder="Name"
                oninput={Callback::from(move |e: InputEvent| {
                    let input: HtmlInputElement = e.target_unchecked_into();
                    set_name.set(input.value());
                })}
            />
            <input
                type="email"
                placeholder="Email"
                oninput={Callback::from(move |e: InputEvent| {
                    let input: HtmlInputElement = e.target_unchecked_into();
                    set_email.set(input.value());
                })}
            />
            <button onclick={submit}>{ "Submit" }</button>
        </>
    }
}

Authentication Flow

use telegram_webapp_sdk::{TelegramWebApp, core::context::TelegramContext};

async fn authenticate() -> Result<(), Box<dyn std::error::Error>> {
    let webapp = TelegramWebApp::new();

    // 1. Get init data
    let raw_init_data = TelegramContext::get_raw_init_data()?;

    // 2. Send to backend for validation
    let response = reqwest::Client::new()
        .post("https://your-api.com/auth")
        .json(&serde_json::json!({
            "init_data": raw_init_data
        }))
        .send()
        .await?;

    if response.status().is_success() {
        let token: String = response.json().await?;
        
        // 3. Store token securely
        secure_storage::set("auth_token", &token, |_| {}).await;
        
        webapp.show_alert("Authenticated!");
    } else {
        webapp.show_alert("Authentication failed");
    }

    Ok(())
}

Next: Chapter 8 - Production Guide

Clone this wiki locally