GitHunt
VI

Vishal-1756/Telegram-Miniapp-Boilerplate

โšก A powerful, modern boilerplate for building Telegram Mini Web Apps using React 18, TypeScript, TailwindCSS, and Vite โ€” featuring full Telegram API support, smooth animations, responsive design, and live feature demos.

๐Ÿš€ Telegram Mini Web App Boilerplate

Telegram WebApp
React
TypeScript
Vite
TailwindCSS

A comprehensive boilerplate for building Telegram Mini Web Apps with modern React stack

๐ŸŽฏ Features โ€ข ๐Ÿš€ Quick Start โ€ข ๐Ÿ“š Documentation โ€ข ๐Ÿ› ๏ธ API Reference โ€ข ๐ŸŒ Deploy


๐ŸŽฏ Features

๐Ÿ”ฅ Core Technologies

  • โšก Vite - Lightning fast build tool and dev server
  • โš›๏ธ React 18 - Latest React with concurrent features
  • ๐ŸŽฏ TypeScript - Full type safety and IntelliSense
  • ๐ŸŽจ Tailwind CSS - Utility-first CSS framework
  • ๐Ÿ”— React Router - Client-side routing
  • ๐Ÿ”„ React Query - Powerful data fetching and caching

๐Ÿ“ฑ Telegram WebApp Integration

  • โœ… Complete API Coverage - All Telegram WebApp methods
  • โœ… Latest Features - Gyroscope, Accelerometer, Device Orientation
  • โœ… Theme Integration - Automatic light/dark mode
  • โœ… Haptic Feedback - Rich tactile feedback
  • โœ… Cloud Storage - Persistent data storage
  • โœ… Biometric Auth - Fingerprint/Face recognition
  • โœ… QR Scanner - Built-in QR code scanning
  • โœ… Location Services - GPS location access
  • โœ… Clipboard Access - Read/write clipboard
  • โœ… Fullscreen Mode - Immersive experience
  • โœ… Story Sharing - Share to Telegram Stories

๐ŸŽจ UI/UX Features

  • ๐ŸŒ™ Dark/Light Mode - Automatic theme switching
  • ๐Ÿ“ฑ Responsive Design - Works on all screen sizes
  • ๐ŸŽญ Modern Components - Beautiful, accessible UI components
  • โšก Smooth Animations - Framer Motion powered
  • ๐ŸŽฏ Interactive Examples - Live feature demonstrations

๐Ÿ–ฅ๏ธ Live Demo

Open Demo

Try out the Telegram Mini Web App boilerplate live!
Scan the QR code below or open the demo link in your telegram.

Demo QR Code


๐Ÿš€ Quick Start

Prerequisites

  • Node.js 18+
  • npm/yarn/pnpm
  • Telegram Bot (create via @BotFather)

Installation

# Clone the repository
git clone https://github.com/vishal-1756/telegram-miniapp-boilerplate.git
cd telegram-miniapp-boilerplate

# Install dependencies
npm install
# or
yarn install
# or
pnpm install

Environment Setup

# Copy environment template
cp .env.example .env

# Edit your environment variables
nano .env
# API Configuration
VITE_API_BASE_URL=https://your-api-domain.com/api

# Bot Configuration  
VITE_BOT_USERNAME=your_bot_username

# Development
VITE_DEV_MODE=true

Development

# Start development server
npm run dev

# Open in browser
# http://localhost:3000

Telegram Bot Setup

  1. Create Bot: Message @BotFather โ†’ /newbot
  2. Set WebApp: /newapp โ†’ Select your bot โ†’ Enter app details
  3. Configure Domain: Add your domain to bot settings
  4. Test: Open your bot โ†’ Menu button โ†’ Your app

๐Ÿ“š Documentation

๐Ÿ—๏ธ Project Structure

src/
โ”œโ”€โ”€ ๐Ÿ“ components/          # Reusable UI components
โ”‚   โ”œโ”€โ”€ ui/                 # Base UI components (Button, Card, etc.)
โ”‚   โ”œโ”€โ”€ TelegramProvider.tsx
โ”‚   โ”œโ”€โ”€ ThemeProvider.tsx
โ”‚   โ”œโ”€โ”€ BackButton.tsx
โ”‚   โ”œโ”€โ”€ MainButton.tsx
โ”‚   โ”œโ”€โ”€ HapticButton.tsx
โ”‚   โ”œโ”€โ”€ UserInfo.tsx
โ”‚   โ”œโ”€โ”€ FeatureCard.tsx
โ”‚   โ””โ”€โ”€ SensorDisplay.tsx
โ”œโ”€โ”€ ๐Ÿ“ hooks/              # Custom React hooks
โ”‚   โ”œโ”€โ”€ useTelegram.ts      # Main Telegram integration
โ”‚   โ”œโ”€โ”€ useBackButton.ts    # Back button management
โ”‚   โ”œโ”€โ”€ useMainButton.ts    # Main button control
โ”‚   โ”œโ”€โ”€ useHapticFeedback.ts # Haptic feedback
โ”‚   โ”œโ”€โ”€ useCloudStorage.ts  # Cloud storage operations
โ”‚   โ”œโ”€โ”€ useBiometric.ts     # Biometric authentication
โ”‚   โ”œโ”€โ”€ useQRScanner.ts     # QR code scanning
โ”‚   โ”œโ”€โ”€ useClipboard.ts     # Clipboard read access
โ”‚   โ”œโ”€โ”€ useWriteClipboard.ts # Clipboard write access
โ”‚   โ”œโ”€โ”€ useLocation.ts      # Location services
โ”‚   โ”œโ”€โ”€ useGyroscope.ts     # Gyroscope sensor
โ”‚   โ”œโ”€โ”€ useAccelerometer.ts # Accelerometer sensor
โ”‚   โ”œโ”€โ”€ useDeviceOrientation.ts # Device orientation
โ”‚   โ”œโ”€โ”€ useFullscreen.ts    # Fullscreen mode
โ”‚   โ”œโ”€โ”€ useOrientation.ts   # Orientation lock
โ”‚   โ”œโ”€โ”€ useHomeScreen.ts    # Home screen installation
โ”‚   โ”œโ”€โ”€ useStorySharing.ts  # Story sharing
โ”‚   โ”œโ”€โ”€ usePopups.ts        # Alerts and popups
โ”‚   โ””โ”€โ”€ useTheme.ts         # Theme management
โ”œโ”€โ”€ ๐Ÿ“ pages/              # Page components
โ”‚   โ”œโ”€โ”€ Home.tsx           # Main landing page
โ”‚   โ”œโ”€โ”€ Features.tsx       # Feature demonstrations
โ”‚   โ”œโ”€โ”€ Sensors.tsx        # Motion sensor testing
โ”‚   โ””โ”€โ”€ Documentation.tsx  # API documentation
โ”œโ”€โ”€ ๐Ÿ“ types/              # TypeScript definitions
โ”‚   โ””โ”€โ”€ telegram.d.ts      # Complete Telegram WebApp types
โ”œโ”€โ”€ ๐Ÿ“ utils/              # Utility functions
โ”‚   โ”œโ”€โ”€ telegram.ts        # Telegram helper functions
โ”‚   โ””โ”€โ”€ api.ts             # API client configuration
โ”œโ”€โ”€ ๐Ÿ“ styles/             # CSS files
โ”‚   โ””โ”€โ”€ globals.css        # Global styles and animations
โ”œโ”€โ”€ App.tsx                # Main app component
โ””โ”€โ”€ main.tsx              # Entry point

๐Ÿ› ๏ธ API Reference

๐ŸŽฏ Core Hooks

useTelegram()

Main hook for Telegram WebApp integration.

import { useTelegram } from '@/hooks/useTelegram'

function MyComponent() {
  const { webApp, user, isReady, platform, version } = useTelegram()
  
  if (!isReady) return <div>Loading...</div>
  
  return (
    <div>
      <h1>Hello, {user?.first_name}!</h1>
      <p>Platform: {platform}</p>
      <p>Version: {version}</p>
    </div>
  )
}

useHapticFeedback()

Provides haptic feedback functionality.

import { useHapticFeedback } from '@/hooks/useHapticFeedback'

function HapticExample() {
  const haptic = useHapticFeedback()
  
  return (
    <div>
      <button onClick={() => haptic.impactLight()}>Light Impact</button>
      <button onClick={() => haptic.impactMedium()}>Medium Impact</button>
      <button onClick={() => haptic.impactHeavy()}>Heavy Impact</button>
      <button onClick={() => haptic.notificationSuccess()}>Success</button>
      <button onClick={() => haptic.notificationError()}>Error</button>
    </div>
  )
}

๐ŸŽฎ UI Control Hooks

useMainButton()

Manages the Telegram main button.

import { useMainButton } from '@/hooks/useMainButton'

function MainButtonExample() {
  const { setText, show, hide, enable, disable } = useMainButton(
    "Continue", 
    () => console.log("Main button clicked!"),
    { color: '#007AFF', is_active: true }
  )
  
  return (
    <div>
      <button onClick={() => setText("New Text")}>Change Text</button>
      <button onClick={show}>Show</button>
      <button onClick={hide}>Hide</button>
    </div>
  )
}

useBackButton()

Handles the back button functionality.

import { useBackButton } from '@/hooks/useBackButton'
import { useNavigate } from 'react-router-dom'

function BackButtonExample() {
  const navigate = useNavigate()
  const { show, hide } = useBackButton(() => navigate(-1))
  
  return (
    <div>
      <button onClick={show}>Show Back Button</button>
      <button onClick={hide}>Hide Back Button</button>
    </div>
  )
}

๐Ÿ’พ Data & Storage Hooks

useCloudStorage()

Telegram cloud storage operations.

import { useCloudStorage } from '@/hooks/useCloudStorage'

function CloudStorageExample() {
  const { setItem, getItem, removeItem, getKeys, loading } = useCloudStorage()
  
  const saveData = async () => {
    await setItem('user_preference', 'dark_mode')
    console.log('Data saved!')
  }
  
  const loadData = async () => {
    const preference = await getItem('user_preference')
    console.log('User preference:', preference)
  }
  
  const getAllKeys = async () => {
    const keys = await getKeys()
    console.log('All keys:', keys)
  }
  
  return (
    <div>
      <button onClick={saveData} disabled={loading}>Save Data</button>
      <button onClick={loadData} disabled={loading}>Load Data</button>
      <button onClick={getAllKeys} disabled={loading}>Get All Keys</button>
    </div>
  )
}

๐Ÿ” Security Hooks

useBiometric()

Biometric authentication (fingerprint/face recognition).

import { useBiometric } from '@/hooks/useBiometric'

function BiometricExample() {
  const { 
    requestAccess, 
    authenticate, 
    updateToken,
    isAvailable, 
    isAccessGranted,
    biometricType 
  } = useBiometric()
  
  const handleAuth = async () => {
    if (!isAvailable) {
      console.log('Biometric not available')
      return
    }
    
    const access = await requestAccess('Authentication required for secure access')
    if (access) {
      const result = await authenticate('Please authenticate to continue')
      if (result.success) {
        console.log('Authentication successful!', result.token)
      }
    }
  }
  
  return (
    <div>
      <p>Biometric Type: {biometricType}</p>
      <p>Available: {isAvailable ? 'Yes' : 'No'}</p>
      <p>Access Granted: {isAccessGranted ? 'Yes' : 'No'}</p>
      <button onClick={handleAuth}>Authenticate</button>
    </div>
  )
}

๐Ÿ“ฑ Device Feature Hooks

useQRScanner()

QR code scanning functionality.

import { useQRScanner } from '@/hooks/useQRScanner'

function QRScannerExample() {
  const { scanQR, closeScan, isScanning } = useQRScanner()
  
  const handleScan = async () => {
    const result = await scanQR('Scan any QR code')
    if (result) {
      console.log('Scanned:', result)
    }
  }
  
  return (
    <div>
      <button onClick={handleScan} disabled={isScanning}>
        {isScanning ? 'Scanning...' : 'Scan QR Code'}
      </button>
      {isScanning && (
        <button onClick={closeScan}>Cancel Scan</button>
      )}
    </div>
  )
}

useLocation()

GPS location services.

import { useLocation } from '@/hooks/useLocation'

function LocationExample() {
  const { getLocation, requestLocation, location, loading } = useLocation()
  
  const handleGetLocation = async () => {
    const loc = await requestLocation()
    if (loc) {
      console.log(`Location: ${loc.latitude}, ${loc.longitude}`)
    }
  }
  
  return (
    <div>
      <button onClick={handleGetLocation} disabled={loading}>
        {loading ? 'Getting Location...' : 'Get Location'}
      </button>
      {location && (
        <div>
          <p>Latitude: {location.latitude}</p>
          <p>Longitude: {location.longitude}</p>
          {location.altitude && <p>Altitude: {location.altitude}m</p>}
        </div>
      )}
    </div>
  )
}

๐Ÿ“‹ Clipboard Hooks

useClipboard() & useWriteClipboard()

Read and write clipboard operations.

import { useClipboard } from '@/hooks/useClipboard'
import { useWriteClipboard } from '@/hooks/useWriteClipboard'

function ClipboardExample() {
  const { readText, loading: readLoading } = useClipboard()
  const { writeText, loading: writeLoading } = useWriteClipboard()
  
  const handleRead = async () => {
    const text = await readText()
    console.log('Clipboard content:', text)
  }
  
  const handleWrite = async () => {
    const success = await writeText('Hello from Telegram WebApp!')
    console.log('Write success:', success)
  }
  
  return (
    <div>
      <button onClick={handleRead} disabled={readLoading}>
        Read Clipboard
      </button>
      <button onClick={handleWrite} disabled={writeLoading}>
        Write to Clipboard
      </button>
    </div>
  )
}

๐ŸŽฏ Motion Sensor Hooks

useGyroscope()

Device rotation rate measurement.

import { useGyroscope } from '@/hooks/useGyroscope'

function GyroscopeExample() {
  const { start, stop, data, isStarted, loading, isAvailable } = useGyroscope()
  
  const handleToggle = async () => {
    if (isStarted) {
      await stop()
    } else {
      await start({ refresh_rate: 100 })
    }
  }
  
  return (
    <div>
      <button onClick={handleToggle} disabled={!isAvailable || loading}>
        {isStarted ? 'Stop' : 'Start'} Gyroscope
      </button>
      {isStarted && (
        <div>
          <p>X: {data.x.toFixed(2)} rad/s</p>
          <p>Y: {data.y.toFixed(2)} rad/s</p>
          <p>Z: {data.z.toFixed(2)} rad/s</p>
        </div>
      )}
    </div>
  )
}

useAccelerometer()

Device acceleration measurement.

import { useAccelerometer } from '@/hooks/useAccelerometer'

function AccelerometerExample() {
  const { start, stop, data, isStarted, loading, isAvailable } = useAccelerometer()
  
  const handleToggle = async () => {
    if (isStarted) {
      await stop()
    } else {
      await start({ refresh_rate: 100 })
    }
  }
  
  return (
    <div>
      <button onClick={handleToggle} disabled={!isAvailable || loading}>
        {isStarted ? 'Stop' : 'Start'} Accelerometer
      </button>
      {isStarted && (
        <div>
          <p>X: {data.x.toFixed(2)} m/sยฒ</p>
          <p>Y: {data.y.toFixed(2)} m/sยฒ</p>
          <p>Z: {data.z.toFixed(2)} m/sยฒ</p>
        </div>
      )}
    </div>
  )
}

useDeviceOrientation()

Device orientation in 3D space.

import { useDeviceOrientation } from '@/hooks/useDeviceOrientation'

function OrientationExample() {
  const { start, stop, data, isStarted, loading, isAvailable } = useDeviceOrientation()
  
  const handleToggle = async () => {
    if (isStarted) {
      await stop()
    } else {
      await start({ refresh_rate: 100, need_absolute: true })
    }
  }
  
  return (
    <div>
      <button onClick={handleToggle} disabled={!isAvailable || loading}>
        {isStarted ? 'Stop' : 'Start'} Orientation
      </button>
      {isStarted && (
        <div>
          <p>Alpha: {data.alpha.toFixed(1)}ยฐ</p>
          <p>Beta: {data.beta.toFixed(1)}ยฐ</p>
          <p>Gamma: {data.gamma.toFixed(1)}ยฐ</p>
          <p>Absolute: {data.absolute ? 'Yes' : 'No'}</p>
        </div>
      )}
    </div>
  )
}

๐ŸŽจ UI Enhancement Hooks

useFullscreen()

Fullscreen mode control.

import { useFullscreen } from '@/hooks/useFullscreen'

function FullscreenExample() {
  const { requestFullscreen, exitFullscreen, isFullscreen, isAvailable } = useFullscreen()
  
  const handleToggle = () => {
    if (isFullscreen) {
      exitFullscreen()
    } else {
      requestFullscreen()
    }
  }
  
  return (
    <div>
      <button onClick={handleToggle} disabled={!isAvailable}>
        {isFullscreen ? 'Exit' : 'Enter'} Fullscreen
      </button>
      <p>Status: {isFullscreen ? 'Fullscreen' : 'Normal'}</p>
    </div>
  )
}

useOrientation()

Device orientation lock.

import { useOrientation } from '@/hooks/useOrientation'

function OrientationLockExample() {
  const { lockOrientation, unlockOrientation, orientation, isLocked, isAvailable } = useOrientation()
  
  const handleToggle = () => {
    if (isLocked) {
      unlockOrientation()
    } else {
      lockOrientation()
    }
  }
  
  return (
    <div>
      <button onClick={handleToggle} disabled={!isAvailable}>
        {isLocked ? 'Unlock' : 'Lock'} Orientation
      </button>
      <p>Current: {orientation}</p>
      <p>Status: {isLocked ? 'Locked' : 'Unlocked'}</p>
    </div>
  )
}

๐Ÿ“ฑ Installation & Sharing Hooks

useHomeScreen()

Add app to device home screen.

import { useHomeScreen } from '@/hooks/useHomeScreen'

function HomeScreenExample() {
  const { addToHomeScreen, checkStatus, status, loading, isAvailable } = useHomeScreen()
  
  const handleAdd = async () => {
    await checkStatus()
    if (status === 'missed') {
      addToHomeScreen()
    }
  }
  
  return (
    <div>
      <button onClick={handleAdd} disabled={!isAvailable || loading}>
        Add to Home Screen
      </button>
      <p>Status: {status}</p>
    </div>
  )
}

useStorySharing()

Share content to Telegram Stories.

import { useStorySharing } from '@/hooks/useStorySharing'

function StoryExample() {
  const { shareToStory, isAvailable } = useStorySharing()
  
  const handleShare = () => {
    shareToStory('https://picsum.photos/400/600', {
      text: 'Check out this amazing app!',
      widget_link: {
        url: 'https://t.me/your_bot',
        name: 'Open App'
      }
    })
  }
  
  return (
    <button onClick={handleShare} disabled={!isAvailable}>
      Share to Story
    </button>
  )
}

๐Ÿ’ฌ Communication Hooks

usePopups()

Native popup dialogs.

import { usePopups } from '@/hooks/usePopups'

function PopupExample() {
  const { showAlert, showConfirm, showPopup } = usePopups()
  
  const handleAlert = () => {
    showAlert('This is an alert message!')
  }
  
  const handleConfirm = async () => {
    const confirmed = await showConfirm('Are you sure you want to continue?')
    console.log('User confirmed:', confirmed)
  }
  
  const handleCustomPopup = async () => {
    const result = await showPopup({
      title: 'Choose an option',
      message: 'What would you like to do?',
      buttons: [
        { id: 'option1', type: 'default', text: 'Option 1' },
        { id: 'option2', type: 'default', text: 'Option 2' },
        { id: 'cancel', type: 'cancel', text: 'Cancel' }
      ]
    })
    console.log('Selected option:', result)
  }
  
  return (
    <div>
      <button onClick={handleAlert}>Show Alert</button>
      <button onClick={handleConfirm}>Show Confirm</button>
      <button onClick={handleCustomPopup}>Show Custom Popup</button>
    </div>
  )
}

๐ŸŽจ UI Components

Basic Components

<Button />

Versatile button component with multiple variants.

import { Button } from '@/components/ui/Button'

function ButtonExample() {
  return (
    <div className="space-x-2">
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="destructive">Destructive</Button>
      
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
      
      <Button loading>Loading...</Button>
      <Button disabled>Disabled</Button>
    </div>
  )
}

<Card />

Flexible card component for content organization.

import { Card, CardHeader, CardContent, CardTitle, CardDescription } from '@/components/ui/Card'

function CardExample() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Card Title</CardTitle>
        <CardDescription>Card description goes here</CardDescription>
      </CardHeader>
      <CardContent>
        <p>Card content...</p>
      </CardContent>
    </Card>
  )
}

<Badge />

Status and category indicators.

import { Badge } from '@/components/ui/Badge'

function BadgeExample() {
  return (
    <div className="space-x-2">
      <Badge variant="default">Default</Badge>
      <Badge variant="success">Success</Badge>
      <Badge variant="warning">Warning</Badge>
      <Badge variant="error">Error</Badge>
      <Badge variant="info">Info</Badge>
    </div>
  )
}

Specialized Components

<HapticButton />

Button with built-in haptic feedback.

import { HapticButton } from '@/components/HapticButton'

function HapticButtonExample() {
  return (
    <div className="space-y-2">
      <HapticButton hapticType="light" onClick={() => console.log('Light haptic')}>
        Light Haptic
      </HapticButton>
      <HapticButton hapticType="medium" onClick={() => console.log('Medium haptic')}>
        Medium Haptic
      </HapticButton>
      <HapticButton hapticType="heavy" onClick={() => console.log('Heavy haptic')}>
        Heavy Haptic
      </HapticButton>
    </div>
  )
}

<FeatureCard />

Specialized card for feature demonstrations.

import { FeatureCard } from '@/components/FeatureCard'

function FeatureCardExample() {
  return (
    <FeatureCard
      title="Cloud Storage"
      description="Store data in Telegram's cloud"
      status="available"
      onTest={() => console.log('Testing feature')}
      icon={<CloudIcon />}
    >
      <p>Additional content goes here...</p>
    </FeatureCard>
  )
}

<UserInfo />

Display Telegram user information.

import { UserInfo } from '@/components/UserInfo'

function UserInfoExample() {
  return <UserInfo />
}

๐ŸŒ Deployment

Deploy to Vercel

  1. Install Vercel CLI

    npm i -g vercel
  2. Login to Vercel

    vercel login
  3. Deploy

    vercel --prod
  4. Set Environment Variables

    vercel env add VITE_API_BASE_URL
    vercel env add VITE_BOT_USERNAME

Deploy to Netlify

  1. Build the project

    npm run build
  2. Deploy via Netlify CLI

    npm install -g netlify-cli
    netlify deploy --prod --dir=dist
  3. Or drag & drop the dist folder to Netlify

Deploy to GitHub Pages

  1. Install gh-pages

    npm install --save-dev gh-pages
  2. Add deploy script to package.json

    {
      "scripts": {
        "deploy": "gh-pages -d dist"
      }
    }
  3. Deploy

    npm run build
    npm run deploy

Deploy to Railway

  1. Connect GitHub repository to Railway
  2. Set environment variables in Railway dashboard
  3. Deploy automatically on git push

๐Ÿ”ง Configuration

Environment Variables

Variable Description Required Default
VITE_API_BASE_URL Backend API base URL No /api
VITE_BOT_USERNAME Telegram bot username No -
VITE_DEV_MODE Development mode flag No false

Telegram Bot Configuration

  1. Create Bot

    /newbot โ†’ Follow instructions
    
  2. Set Menu Button

    /setmenubutton โ†’ Select bot โ†’ Send web app URL
    
  3. Configure Domain

    /setdomain โ†’ Select bot โ†’ Add your domain
    
  4. Set Commands (Optional)

    /setcommands โ†’ Select bot โ†’ Add commands:
    start - Start the bot
    help - Get help
    app - Open Mini App
    

๐Ÿงช Testing

Development Testing

# Start development server
npm run dev

# Test in browser
open http://localhost:3000

Telegram Testing

  1. Use ngrok for local testing

    npm install -g ngrok
    ngrok http 3000
  2. Update bot WebApp URL with ngrok URL

  3. Test in Telegram

    • Open your bot
    • Click menu button
    • Test all features

Production Testing

  1. Deploy to staging environment
  2. Update bot with staging URL
  3. Test all features thoroughly
  4. Deploy to production

๐Ÿ”’ Security Best Practices

1. Validate Init Data

// Backend validation example
import crypto from 'crypto'

function validateTelegramWebAppData(initData: string, botToken: string): boolean {
  const urlParams = new URLSearchParams(initData)
  const hash = urlParams.get('hash')
  urlParams.delete('hash')
  
  const dataCheckString = Array.from(urlParams.entries())
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([key, value]) => `${key}=${value}`)
    .join('\n')
  
  const secretKey = crypto.createHmac('sha256', 'WebAppData').update(botToken).digest()
  const calculatedHash = crypto.createHmac('sha256', secretKey).update(dataCheckString).digest('hex')
  
  return calculatedHash === hash
}

2. Sanitize User Input

import DOMPurify from 'dompurify'

function sanitizeInput(input: string): string {
  return DOMPurify.sanitize(input)
}

3. Rate Limiting

// Example rate limiting middleware
const rateLimit = require('express-rate-limit')

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
})

app.use('/api/', limiter)

4. HTTPS Only

// Redirect HTTP to HTTPS
app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    res.redirect(`https://${req.header('host')}${req.url}`)
  } else {
    next()
  }
})

๐Ÿ› Troubleshooting

Common Issues

1. WebApp not loading in Telegram

# Check console for errors
# Ensure HTTPS is enabled
# Verify bot configuration
# Check domain whitelist

2. Features not working

// Check Telegram version
const { webApp } = useTelegram()
if (webApp?.isVersionAtLeast('6.4')) {
  // Feature available
} else {
  // Feature not supported
}

3. Theme not applying

// Ensure ThemeProvider is wrapping your app
<TelegramProvider>
  <ThemeProvider>
    <App />
  </ThemeProvider>
</TelegramProvider>

4. Haptic feedback not working

// Check if running in Telegram
import { isTelegramWebApp } from '@/utils/telegram'

if (isTelegramWebApp()) {
  haptic.impactMedium()
} else {
  console.log('Haptic feedback only works in Telegram')
}

Debug Mode

// Enable debug logging
localStorage.setItem('telegram-debug', 'true')

// Check WebApp availability
console.log('Telegram WebApp:', window.Telegram?.WebApp)
console.log('User:', window.Telegram?.WebApp?.initDataUnsafe?.user)

๐Ÿค Contributing

We welcome contributions! Please follow these steps:

1. Fork & Clone

git clone https://github.com/vishal-1756/telegram-miniapp-boilerplate.git
cd telegram-miniapp-boilerplate

2. Create Feature Branch

git checkout -b feature/amazing-feature

3. Make Changes

  • Follow existing code style
  • Add TypeScript types
  • Include tests if applicable
  • Update documentation

4. Commit Changes

git commit -m "feat: add amazing feature"

5. Push & Create PR

git push origin feature/amazing-feature

Code Style

  • TypeScript: Strict mode enabled
  • ESLint: Follow provided configuration
  • Prettier: Auto-formatting enabled
  • Naming: Use camelCase for variables, PascalCase for components

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿ†˜ Support & Resources

๐Ÿ“š Documentation

๐Ÿ’ฌ Community

๐Ÿ› Issues

๐Ÿ“ง Contact


โœ… Completed

  • Complete Telegram WebApp API coverage
  • Motion sensors integration
  • Modern UI components
  • TypeScript definitions
  • Comprehensive documentation

โญ Show Your Support

If this project helped you, please consider:

  • โญ Starring the repository
  • ๐Ÿ› Reporting bugs and issues
  • ๐Ÿ’ก Suggesting new features
  • ๐Ÿค Contributing to the codebase
  • ๐Ÿ“ข Sharing with the community

Built with โค๏ธ for the Telegram Mini App ecosystem

โฌ† Back to Top

Languages

TypeScript97.8%CSS1.3%JavaScript0.5%HTML0.4%

Contributors

Latest Release

fixedMay 31, 2025
Apache License 2.0
Created May 30, 2025
Updated October 23, 2025
Vishal-1756/Telegram-Miniapp-Boilerplate | GitHunt