admin管理员组文章数量:1309955
I have a Next.js project, which is a Telegram Mini-App. It's a simple ecommerce template, and I use TypeScript and React.
To have access to the current Telegram user or Mini-App methods globally I use the useContext()
hook. I have ./lib/TelegramProvider.tsx
file that handles that. It looks like this:
"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=".js"
strategy="beforeInteractive"
/>
{children}
</TelegramContext.Provider>
);
};
export const useTelegram = () => useContext(TelegramContext);
Then, I wrap all the content of the app in <TelegramProvider><TelegramProvider/>
in ./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>
);
}
So that later, I can access it in ./src/app/product/[slug]/page.tsx
like this:
"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 product component code, I can use user.username to display the username */}
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;
The problem is that, I currently rely on the <Script src=".js" strategy="beforeInteractive"/>
line in my TelegramProvider
for @telegram-apps/sdk to work. The SDK doesn't function without this line. I want to remove it and work only with the SDK, as it is recommended in their documentation. But whenever I remove it, the app breaks. I suspect it is because I can't properly initialize it. I've been trying to debug and make at least app.requestFullscreen();
work, but no luck. It is very confusing, the SDK appears to be dependant on telegram-web-app.js
, although it is meant to be used standalone. Coming to StackOverflow is truly my last resort.
- I tried simply removing the
<Script src=".js" strategy="beforeInteractive"/>
line. I expected the app to break and it did. - Then, I realized that I need to initialize it per the documentation. I
import { init } from '@telegram-apps/sdk';
at the top ofTelegramProvider
and then tried callinginit()
. - I called
init();
inside of the useEffect hook, right before declaring theapp
const. I expected it to work just like that. It didn't. I calledinit()
after theapp
declaration, no luck. Then, I called it inside of theif
statement. No luck. Then I called it right after declaring theITelegramContext
interface, and it didn't work still. - I realized that I clearly had a gap of understanding of the SDK and I spent some time reading the documentation. I learned quite a lot, including the fact that I could've used more suitable
@telegram-apps/sdk-react
version, but it didn't get me anywhere near understanding how to initialize the library. - I went on GitHub and started searching if I could find a code where people have already implemented this function, but no luck.
- I went looking inside the module itself, and only found the declaration of the function in
@telegram-apps/sdk/dist/dts/init.d.ts
, not the body. I was hoping to see what this function does to understand where exactly I should be putting it.
本文标签: reactjsHow can I make telegramappssdk work without telegramwebappjsStack Overflow
版权声明:本文标题:reactjs - How can I make @telegram-appssdk work without telegram-web-app.js? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741860987a2401623.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论