## `vue-tg` - Telegram integration for Vue [![docs](https://img.shields.io/badge/Documentation-gray?style=flat)](https://vue-tg.deptyped.com/) [![version](https://img.shields.io/badge/Bot%20API-9.5-478be6?logo=telegram&style=flat)](https://core.telegram.org/bots/webapps#march-1-2026) [![downloads](https://img.shields.io/npm/dm/vue-tg?label=Downloads&logo=npm&style=flat&color=478be6)](https://www.npmjs.com/package/vue-tg) A lightweight package for seamless integration of [Telegram Mini Apps](https://core.telegram.org/bots/webapps) and [Telegram Widgets](https://core.telegram.org/widgets) features. ### Usage Example ```vue ``` ### Installation Install package: ```bash npm i vue-tg ``` To connect your Mini App to the Telegram client, place the script `telegram-web-app.js` in the `` tag before any other scripts, using this code: ```html ``` - [Documentation](https://vue-tg.deptyped.com/mini-apps.html) - [Field Mapping](https://vue-tg.deptyped.com/mini-apps.html#field-mapping) - [Event Handling](https://vue-tg.deptyped.com/mini-apps.html#event-handling) ## Features ### Type Safety In addition to static typing, the library enforces runtime feature support checks to prevent errors on clients with outdated Bot API support. ```ts const deviceStorage = useDeviceStorage() // ❌ Type error: // 'getItem' may not be available — DeviceStorage was introduced in Bot API 9.0 deviceStorage.getItem('token') if (deviceStorage.isVersionAtLeast('9.0')) { // ✅ Safe to use deviceStorage.getItem('token') } ``` You can opt out of these checks or define a minimum required Bot API version, which disables warnings for features introduced up to that version. For details, see [the versioning section in the documentation](https://vue-tg.deptyped.com/mini-apps.html#version-check). ### Reactivity You can react to changes using the standard Vue reactivity pattern: ```ts const miniApp = useMiniApp() watch(miniApp.isActive, (isActive) => { if (isActive) startUpdating() else stopUpdating() }) ``` The `isActive` field is reactive, so it can be used in `watch`, `computed`, or any other reactive context. In [the documentation](https://vue-tg.deptyped.com/mini-apps.html), all reactive fields are marked with **reactive** tag. ### Async Support You can use `async`/`await` to work with methods — no need to nest callbacks. ```ts const miniApp = useMiniApp() const qrScanner = useQrScanner() const popup = usePopup() // Old callback-style flow qrScanner.show({ text: 'Scan URL' }, (url) => { popup.showConfirm(`Open ${url}?`, (ok) => { if (ok) { miniApp.openLink(url) } }) }) // The modern way — flat and readable const url = await qrScanner.show({ text: 'Scan URL' }) const ok = await popup.showConfirm(`Open ${url}?`) if (ok) { miniApp.openLink(url) } ``` Methods that support async execution are marked with **async** tag in [the documentation](https://vue-tg.deptyped.com/mini-apps.html). Callback-style usage is still available for compatibility. ### Components Available components: - [Alert](https://vue-tg.deptyped.com/mini-apps.html#alert) - [BackButton](https://vue-tg.deptyped.com/mini-apps.html#backbutton) - [BiometricManager](https://vue-tg.deptyped.com/mini-apps.html#biometricmanager) - [ClosingConfirmation](https://vue-tg.deptyped.com/mini-apps.html#closingconfirmation) - [Confirm](https://vue-tg.deptyped.com/mini-apps.html#confirm) - [ExpandedViewport](https://vue-tg.deptyped.com/mini-apps.html#expandedviewport) - [FullscreenViewport](https://vue-tg.deptyped.com/mini-apps.html#fullscreenviewport) - [MainButton](https://vue-tg.deptyped.com/mini-apps.html#mainbutton) - [Popup](https://vue-tg.deptyped.com/mini-apps.html#popup) - [ScanQr](https://vue-tg.deptyped.com/mini-apps.html#scanqr) - [SecondaryButton](https://vue-tg.deptyped.com/mini-apps.html#secondarybutton) - [SettingsButton](https://vue-tg.deptyped.com/mini-apps.html#settingsbutton) ### Widgets - [Share Widget](https://vue-tg.deptyped.com/widgets#share-widget) - [Post Widget](https://vue-tg.deptyped.com/widgets#post-widget) - [Login Widget](https://vue-tg.deptyped.com/widgets#login-widget) - [Discussion Widget](https://vue-tg.deptyped.com/widgets#discussion-widget) ## Documentation ### Instructions - [Global Registration of Components](https://vue-tg.deptyped.com/installation.html#global-aliases) - [Using with Nuxt 3](https://vue-tg.deptyped.com/installation.html#using-with-nuxt-3) #### Mapping | Field | Composable | | ---------------------------- | ------------------------------------------------------------------------------------------------------- | | initData | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | initDataUnsafe | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | version | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | platform | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | colorScheme | [useTheme](https://vue-tg.deptyped.com/mini-apps.html#usetheme) | | themeParams | [useTheme](https://vue-tg.deptyped.com/mini-apps.html#usetheme) | | isActive | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | isExpanded | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | viewportHeight | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | viewportStableHeight | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | headerColor | [useTheme](https://vue-tg.deptyped.com/mini-apps.html#usetheme) | | backgroundColor | [useTheme](https://vue-tg.deptyped.com/mini-apps.html#usetheme) | | isClosingConfirmationEnabled | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | isVerticalSwipesEnabled | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | isFullscreen | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | isOrientationLocked | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | safeAreaInset | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | contentSafeAreaInset | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | BackButton | [useBackButton](https://vue-tg.deptyped.com/mini-apps.html#usebackbutton) | | MainButton | [useMainButton](https://vue-tg.deptyped.com/mini-apps.html#usemainbutton) | | SecondaryButton | [useSecondaryButton](https://vue-tg.deptyped.com/mini-apps.html#usesecondarybutton) | | SettingsButton | [useSettingsButton](https://vue-tg.deptyped.com/mini-apps.html#usesettingsbutton) | | HapticFeedback | [useHapticFeedback](https://vue-tg.deptyped.com/mini-apps.html#usehapticfeedback) | | CloudStorage | [useCloudStorage](https://vue-tg.deptyped.com/mini-apps.html#usecloudstorage) | | BiometricManager | [useBiometricManager](https://vue-tg.deptyped.com/mini-apps.html#usebiometricmanager) | | Accelerometer | [useAccelerometer](https://vue-tg.deptyped.com/mini-apps.html#useaccelerometer) | | DeviceOrientation | [useDeviceOrientation](https://vue-tg.deptyped.com/mini-apps.html#usedeviceorientation) | | Gyroscope | [useGyroscope](https://vue-tg.deptyped.com/mini-apps.html#usegyroscope) | | LocationManager | [useLocationManager](https://vue-tg.deptyped.com/mini-apps.html#uselocationmanager) | | DeviceStorage | [useDeviceStorage](https://vue-tg.deptyped.com/mini-apps.html#usedevicestorage) | | SecureStorage | [useSecureStorage](https://vue-tg.deptyped.com/mini-apps.html#usesecurestorage) | | isVersionAtLeast | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | setHeaderColor | [useTheme](https://vue-tg.deptyped.com/mini-apps.html#usetheme) | | setBackgroundColor | [useTheme](https://vue-tg.deptyped.com/mini-apps.html#usetheme) | | setBottomBarColor | [useTheme](https://vue-tg.deptyped.com/mini-apps.html#usetheme) | | enableClosingConfirmation | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | disableClosingConfirmation | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | enableVerticalSwipes | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | disableVerticalSwipes | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | requestFullscreen | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | exitFullscreen | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | lockOrientation | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | unlockOrientation | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | addToHomeScreen | [useHomeScreen](https://vue-tg.deptyped.com/mini-apps.html#usehomescreen) | | checkHomeScreenStatus | [useHomeScreen](https://vue-tg.deptyped.com/mini-apps.html#usehomescreen) | | onEvent | [Event Handling](https://vue-tg.deptyped.com/mini-apps.html#event-handling) | | offEvent | [Managing Event Subscriptions](https://vue-tg.deptyped.com/mini-apps.html#managing-event-subscriptions) | | sendData | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | switchInlineQuery | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | openLink | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | openTelegramLink | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | openInvoice | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | shareToStory | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | shareMessage | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | setEmojiStatus | [useEmojiStatus](https://vue-tg.deptyped.com/mini-apps.html#useemojistatus) | | requestEmojiStatusAccess | [useEmojiStatus](https://vue-tg.deptyped.com/mini-apps.html#useemojistatus) | | downloadFile | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | hideKeyboard | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | showPopup | [usePopup](https://vue-tg.deptyped.com/mini-apps.html#usepopup) | | showAlert | [usePopup](https://vue-tg.deptyped.com/mini-apps.html#usepopup) | | showConfirm | [usePopup](https://vue-tg.deptyped.com/mini-apps.html#usepopup) | | showScanQrPopup | [useQrScanner](https://vue-tg.deptyped.com/mini-apps.html#useqrscanner) | | closeScanQrPopup | [useQrScanner](https://vue-tg.deptyped.com/mini-apps.html#useqrscanner) | | readTextFromClipboard | [useClipboard](https://vue-tg.deptyped.com/mini-apps.html#useclipboard) | | requestWriteAccess | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | requestContact | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | ready | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) | | expand | [useViewport](https://vue-tg.deptyped.com/mini-apps.html#useviewport) | | close | [useMiniApp](https://vue-tg.deptyped.com/mini-apps.html#useminiapp) |