如何让@telegram-apps/sdk脱离telegram-web-app.js独立运行?
如何脱离telegram-web-app.js独立初始化@telegram-apps/sdk
背景
我基于Next.js、TypeScript和React开发了一款Telegram迷你电商应用,通过useContext钩子全局管理Telegram用户及迷你应用方法,实现了./lib/TelegramProvider.tsx组件处理相关逻辑,并在./src/app/layout.tsx中用该组件包裹整个应用内容,页面里通过useTelegram获取用户和应用数据。
现有代码
TelegramProvider组件 (./lib/TelegramProvider.tsx)
"use client"; import Script from "next/script"; import { createContext, useContext, useEffect, useMemo, useState } from "react"; import { postEvent } from "@telegram-apps/sdk"; import { on } from "@telegram-apps/bridge"; import { init } from "@telegram-apps/sdk"; import type { ITelegramUser, IWebApp } from "./types"; export interface ITelegramContext { webApp?: IWebApp; user?: ITelegramUser; } export const TelegramContext = createContext<ITelegramContext>({}); export const TelegramProvider = ({ children, }: { children: React.ReactNode; }) => { const [webApp, setWebApp] = useState<any | null>(null); useEffect(() => { const app = (window as any)?.Telegram?.WebApp; if (app) { app.ready(); setWebApp(app); // Global rules // app.enableClosingConfirmation(); // Enable closing confirmation app.disableVerticalSwipes(); // Disable vertical swipes app.requestFullscreen(); } }, []); const value = useMemo(() => { return webApp ? { webApp, unsafeData: webApp.initDataUnsafe, user: webApp.initDataUnsafe?.user, } : {}; }, [webApp]); return ( <TelegramContext.Provider value={value}> <Script src="https://telegram.org/js/telegram-web-app.js" strategy="beforeInteractive" /> {children} </TelegramContext.Provider> ); }; export const useTelegram = () => useContext(TelegramContext);
RootLayout (./src/app/layout.tsx)
import type { Metadata } from "next"; import "./globals.css"; import HeaderWithRoundedCorners from "./components/HeaderWithRoundedCorners"; import { TelegramProvider } from "../../lib/TelegramProvider"; export const metadata: Metadata = { title: "My app", description: "My app description", }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en" suppressHydrationWarning> <head> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=1.0, user-scalable=0"/> </head> <body className={`antialiased`}> <div className="wrapper"> <HeaderWithRoundedCorners><></></HeaderWithRoundedCorners> <TelegramProvider>{children}</TelegramProvider> </div> </body> </html> ); }
页面使用示例 (ProductPage)
"use client"; import { useTelegram } from "../../../../lib/TelegramProvider"; import React, { useEffect, useState } from "react"; import { useParams, notFound } from "next/navigation"; import ProductTabs from "../components/ProductTabs"; import Carousel from "../components/Carousel"; import PriceDisplay from "../components/PriceDisplay"; import DeliveryInfo from "../components/DeliveryInfo"; // export const products = [] dummy array const ProductPage: React.FC = () => { const { slug } = useParams(); const { webApp, user } = useTelegram(); // Access Telegram user and app data const product = products.find((p) => p.id === slug) || null; if (!product) return notFound(); return ( <div className=""> {/* Display Telegram username for testing */} {user ? ( <div className="mb-4 text-sm text-gray-500"> Logged in as: <span className="font-bold">{user.username}</span> </div> ) : ( <div className="mb-4 text-sm text-red-500"> User data not available. Make sure to open this app in Telegram. </div> )} {/* Carousel Section */} <div className="mb-6"> <Carousel images={product.images} peek="20" /> </div> {/* Price Section */} <div className="mb-6"> <PriceDisplay price={product.price} previousPrice={product.previousPrice} /> </div> {/* Delivery Info Section */} <div className="mb-6"> <DeliveryInfo {...deliveryData} /> </div> {/* Page Header */} <h1 className="text-2xl font-bold mx-4">{product.name}</h1> {/* Product Tabs Section */} <ProductTabs description={product.description} properties={product.properties} /> </div> ); }; export default ProductPage;
问题
目前应用必须依赖<Script src="https://telegram.org/js/telegram-web-app.js" strategy="beforeInteractive"/>才能让@telegram-apps/sdk正常运行,但官方文档推荐仅使用SDK独立运行。移除该脚本后应用直接崩溃,我尝试了以下方案均无效:
- 在
useEffect内外不同位置调用init方法; - 查阅
@telegram-apps/sdk-react文档但未掌握正确初始化方式; - 搜索GitHub案例、查看模块源码均未找到可行解决方案。
求问如何正确初始化@telegram-apps/sdk,使其脱离telegram-web-app.js独立运行,同时保证app.requestFullscreen()这类方法正常工作。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

