diff --git a/package-lock.json b/package-lock.json
index e25a042..d688d40 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,8 @@
"@radix-ui/react-tooltip": "^1.2.8",
"@radix-ui/react-visually-hidden": "^1.2.4",
"@tanstack/react-query": "^5.8.0",
- "@tma.js/sdk-react": "^3.0.15",
+ "@telegram-apps/react-router-integration": "^1.0.1",
+ "@telegram-apps/sdk-react": "^3.3.9",
"axios": "^1.6.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -37,7 +38,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^13.5.0",
- "react-router-dom": "^7.13.0",
+ "react-router-dom": "^6.30.3",
"tailwind-merge": "^3.4.0",
"zustand": "^4.4.0"
},
@@ -2266,6 +2267,15 @@
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
"license": "MIT"
},
+ "node_modules/@remix-run/router": {
+ "version": "1.23.2",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz",
+ "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.53",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
@@ -2607,47 +2617,60 @@
"react": "^18 || ^19"
}
},
- "node_modules/@tma.js/bridge": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/@tma.js/bridge/-/bridge-2.2.2.tgz",
- "integrity": "sha512-dL7iZzYP/VC4/qJYSXPI1GXLGP3gLTp10L7iGY6PcjB2F4xXS2JnHUoYvD2DgQG1ogjE93zWnVIMN7inx1v+Eg==",
+ "node_modules/@telegram-apps/bridge": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/bridge/-/bridge-2.11.0.tgz",
+ "integrity": "sha512-kBZjWRRp/lxKeQ8r8cDWUY9EjxUtyeh/9xTQjsjuGRsCR5XTO1cyVbvcvqzHn53csGx3aBs+fOR3Pk3b6w2JHg==",
+ "deprecated": "This package is not supported anymore. Use @tma.js/bridge instead",
"license": "MIT",
"dependencies": {
- "@tma.js/signals": "^1.0.1",
- "@tma.js/toolkit": "^1.0.4",
- "@tma.js/transformers": "^1.1.3",
- "@tma.js/types": "^1.0.2",
- "better-promises": "^1.0.0",
- "error-kid": "^1.0.2",
- "fp-ts": "^2.16.11",
+ "@telegram-apps/signals": "^1.1.2",
+ "@telegram-apps/toolkit": "^2.1.3",
+ "@telegram-apps/transformers": "^2.2.6",
+ "@telegram-apps/types": "^2.0.3",
+ "better-promises": "^0.4.1",
+ "error-kid": "^0.0.7",
"mitt": "^3.0.1",
- "valibot": "^1.1.0"
+ "valibot": "1.0.0"
}
},
- "node_modules/@tma.js/sdk": {
- "version": "3.1.6",
- "resolved": "https://registry.npmjs.org/@tma.js/sdk/-/sdk-3.1.6.tgz",
- "integrity": "sha512-NENkQa7G5N9kwbL20ErUMO9Fukxl9eVhcJ439PbCg2WYMk/x9oNbx2DhEzhX4xM718zSjYejmSj1oXCKk0PxYA==",
+ "node_modules/@telegram-apps/navigation": {
+ "version": "1.0.14",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/navigation/-/navigation-1.0.14.tgz",
+ "integrity": "sha512-bqNgF/J8Po7ZtsELm3E1a6aPr7awwxO3sIqD8J6u12urOlGoW5+1KxKKbkPa58mgXuQdsltd8apI+OVy0IYiUA==",
+ "license": "MIT"
+ },
+ "node_modules/@telegram-apps/react-router-integration": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/react-router-integration/-/react-router-integration-1.0.1.tgz",
+ "integrity": "sha512-q5fC0ihXyUDqrSdLQ3u3gypmjI/rMU2mTHeAz9IU1F1bl5X+J17LxWmgLp+OlD0Y97bq2XYmc+UbKrYh+eN3Wg==",
"license": "MIT",
- "dependencies": {
- "@tma.js/bridge": "^2.2.2",
- "@tma.js/signals": "^1.0.1",
- "@tma.js/toolkit": "^1.0.4",
- "@tma.js/transformers": "^1.1.3",
- "@tma.js/types": "^1.0.2",
- "better-promises": "^1.0.0",
- "error-kid": "^1.0.2",
- "fp-ts": "^2.16.11",
- "valibot": "^1.1.0"
+ "peerDependencies": {
+ "@telegram-apps/sdk": "^1",
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0",
+ "react-router-dom": "^6.22.3"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
}
},
- "node_modules/@tma.js/sdk-react": {
- "version": "3.0.15",
- "resolved": "https://registry.npmjs.org/@tma.js/sdk-react/-/sdk-react-3.0.15.tgz",
- "integrity": "sha512-HsgqPINSBK87NIRZ+ZDol07QPhSQ3GOTofyZEH0xoaQjZWb9wVxUXwECa5ozRUdzWZI+Mgx8oD1pzrjyNkDjFA==",
+ "node_modules/@telegram-apps/sdk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/sdk/-/sdk-1.1.3.tgz",
+ "integrity": "sha512-gvcXNttbCouDNTxjDUbO5FS/BdaHYO0ibSddQxiYitShPIDZDxGon0Eh3OSsgUIVPSQSNdXqkXaeqYgA+jeY0A==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@telegram-apps/sdk-react": {
+ "version": "3.3.9",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/sdk-react/-/sdk-react-3.3.9.tgz",
+ "integrity": "sha512-85jF1ICT8sYCNzXu19SqJrfrS8XslsvV14KUcToiyL7H5ZMXHt0JQKM+QJgULjnLjEswweQ4/7Bd7mNULf/BIg==",
"license": "MIT",
"dependencies": {
- "@tma.js/sdk": "^3.1.6"
+ "@telegram-apps/sdk": "^3.11.8"
},
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
@@ -2659,38 +2682,66 @@
}
}
},
- "node_modules/@tma.js/signals": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@tma.js/signals/-/signals-1.0.1.tgz",
- "integrity": "sha512-i2HUuwGqL4BmM5KAklAUhMhlEgUOF+F4nMHHS/zxrmD0upHE/0CiXCEdQxVeeOGN6e2RrKlonA40sDtR6OUDCw==",
+ "node_modules/@telegram-apps/sdk-react/node_modules/@telegram-apps/sdk": {
+ "version": "3.11.8",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/sdk/-/sdk-3.11.8.tgz",
+ "integrity": "sha512-vlpkYzMJCV9Cadsn9Q+/hbHNR39j5o96N9z4CjZ6AFHkkxOeOqVRrq9zRBw0gmffROkF2bU0WQxhRj8KZ/bPhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@telegram-apps/bridge": "^2.11.0",
+ "@telegram-apps/navigation": "^1.0.14",
+ "@telegram-apps/signals": "^1.1.2",
+ "@telegram-apps/toolkit": "^2.1.3",
+ "@telegram-apps/transformers": "^2.2.6",
+ "@telegram-apps/types": "^2.0.3",
+ "better-promises": "^0.4.1",
+ "error-kid": "^0.0.7",
+ "valibot": "1.0.0"
+ }
+ },
+ "node_modules/@telegram-apps/signals": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/signals/-/signals-1.1.2.tgz",
+ "integrity": "sha512-1P1kdCLX7MfETGPxH7f3UZKIsdE7Tz5S7QmN4Km1sbYQMakD5Bi1NecSMR7/wnHp50gWMI1JzENcMtCEmouhSg==",
"license": "MIT"
},
- "node_modules/@tma.js/toolkit": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@tma.js/toolkit/-/toolkit-1.0.4.tgz",
- "integrity": "sha512-6CDlkgc+43WD2jy6jog3B50yt9t+/wRwrN25zOa4iSw4IzfqoFjaQcJzTupBYaRxz19C3Rrir7p0/qStS/Z8vw==",
+ "node_modules/@telegram-apps/toolkit": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/toolkit/-/toolkit-2.1.3.tgz",
+ "integrity": "sha512-LPUBL7hxQTOr+Dowyk9a1O82nQS4ja4+OYiYWtvqq5nNUHC6Gbbus0zGWCbFcj9CLnIzaeb5HWOg5iSnhoRcyg==",
+ "license": "MIT"
+ },
+ "node_modules/@telegram-apps/transformers": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/transformers/-/transformers-2.2.6.tgz",
+ "integrity": "sha512-MMBRs3demeBT9Cd614KKZmak7eEyNdEbfu99a0SwEEJe2oIODjJLrUxrhUcAOc5wvTRfrKka27VXVgruauLhdg==",
+ "deprecated": "This package is not supported anymore. Use @tma.js/transfomers instead",
"license": "MIT",
"dependencies": {
- "better-promises": "^1.0.0",
- "fp-ts": "^2.16.11"
+ "@telegram-apps/toolkit": "^2.1.3",
+ "@telegram-apps/types": "^2.0.3",
+ "valibot": "1.0.0-beta.14"
}
},
- "node_modules/@tma.js/transformers": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@tma.js/transformers/-/transformers-1.1.3.tgz",
- "integrity": "sha512-zRL+fdo/NBpGqCJfl8ItAvcJIFT5Zy6UOYJwQPmUV5/gTHgmSvmGlrP43PeVi9XZ7Ggf4xbO6LUa4ehxozhMTA==",
+ "node_modules/@telegram-apps/transformers/node_modules/valibot": {
+ "version": "1.0.0-beta.14",
+ "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.14.tgz",
+ "integrity": "sha512-tLyV2rE5QL6U29MFy3xt4AqMrn+/HErcp2ZThASnQvPMwfSozjV1uBGKIGiegtZIGjinJqn0SlBdannf18wENA==",
"license": "MIT",
- "dependencies": {
- "@tma.js/toolkit": "^1.0.4",
- "@tma.js/types": "^1.0.2",
- "fp-ts": "^2.16.11",
- "valibot": "^1.1.0"
+ "peerDependencies": {
+ "typescript": ">=5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
},
- "node_modules/@tma.js/types": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@tma.js/types/-/types-1.0.2.tgz",
- "integrity": "sha512-qs4mi+U1xZmMQBdMhWAo1X4YqUJ/ae0y28s+GNCpQq58bsJo0h8rvyVOB1RwPvXogIY9+yribbZe6z3AIJmsAQ==",
+ "node_modules/@telegram-apps/types": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@telegram-apps/types/-/types-2.0.3.tgz",
+ "integrity": "sha512-pXh9BdnLZF3e2BGc4WL+RTRMAUpqKpaSP3Rs8rB4WyRwIoRSGWFKE4gtT/9m42LGixB8YVwdo/pJ+9XO765XEA==",
+ "deprecated": "This package is not supported anymore. Use @tma.js/types instead",
"license": "MIT"
},
"node_modules/@types/babel__core": {
@@ -3282,12 +3333,12 @@
}
},
"node_modules/better-promises": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/better-promises/-/better-promises-1.0.0.tgz",
- "integrity": "sha512-gPgL2nRgeSbMIe3QpsYdKR3K0S9OZuphVuos60Eqsw8d/6GivOkyJ5D/zmnolJ6hzh7upnnflBUWUlQh4qpU2A==",
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/better-promises/-/better-promises-0.4.1.tgz",
+ "integrity": "sha512-cDW7eMvhvCoWzSih5o/OxsAgTUfP05yGMq77xNZUTmcZoNU9vEeFZJ+yJJi4lnocvxFrVFKsG0Yxt7ZnuYJEig==",
"license": "MIT",
"dependencies": {
- "error-kid": "^1.0.1"
+ "error-kid": "^0.0.7"
}
},
"node_modules/binary-extensions": {
@@ -3604,19 +3655,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/cookie": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
- "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -3757,9 +3795,9 @@
}
},
"node_modules/error-kid": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/error-kid/-/error-kid-1.0.2.tgz",
- "integrity": "sha512-Xvq0ZrY/azCbREWKt9E/3mXDF0MkuEVVvHnOKutUhtq2O8pyneEixQ4nSFkA19Xfn+/OVSg//iVG0dxIDj7DIA==",
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/error-kid/-/error-kid-0.0.7.tgz",
+ "integrity": "sha512-8mFs7ZaDWlBFgjOy4lHLMCe2+KZfZXGx5GOgh2VQ/M1CCIvSWzbl2OMl+5fdZgrgoUfhTeF+NPhmqfEvUhN8yw==",
"license": "MIT"
},
"node_modules/es-define-property": {
@@ -4241,12 +4279,6 @@
"node": ">= 6"
}
},
- "node_modules/fp-ts": {
- "version": "2.16.11",
- "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.11.tgz",
- "integrity": "sha512-LaI+KaX2NFkfn1ZGHoKCmcfv7yrZsC3b8NtWsTVQeHkq4F27vI5igUuO53sxqDEa2gNQMHFPmpojDw/1zmUK7w==",
- "license": "MIT"
- },
"node_modules/fraction.js": {
"version": "5.3.4",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
@@ -5679,41 +5711,36 @@
}
},
"node_modules/react-router": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz",
- "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==",
+ "version": "6.30.3",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz",
+ "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==",
"license": "MIT",
"dependencies": {
- "cookie": "^1.0.1",
- "set-cookie-parser": "^2.6.0"
+ "@remix-run/router": "1.23.2"
},
"engines": {
- "node": ">=20.0.0"
+ "node": ">=14.0.0"
},
"peerDependencies": {
- "react": ">=18",
- "react-dom": ">=18"
- },
- "peerDependenciesMeta": {
- "react-dom": {
- "optional": true
- }
+ "react": ">=16.8"
}
},
"node_modules/react-router-dom": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.0.tgz",
- "integrity": "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==",
+ "version": "6.30.3",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz",
+ "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==",
"license": "MIT",
+ "peer": true,
"dependencies": {
- "react-router": "7.13.0"
+ "@remix-run/router": "1.23.2",
+ "react-router": "6.30.3"
},
"engines": {
- "node": ">=20.0.0"
+ "node": ">=14.0.0"
},
"peerDependencies": {
- "react": ">=18",
- "react-dom": ">=18"
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
}
},
"node_modules/react-style-singleton": {
@@ -5915,12 +5942,6 @@
"node": ">=10"
}
},
- "node_modules/set-cookie-parser": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
- "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
- "license": "MIT"
- },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -6414,9 +6435,9 @@
"license": "MIT"
},
"node_modules/valibot": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.2.0.tgz",
- "integrity": "sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0.tgz",
+ "integrity": "sha512-1Hc0ihzWxBar6NGeZv7fPLY0QuxFMyxwYR2sF1Blu7Wq7EnremwY2W02tit2ij2VJT8HcSkHAQqmFfl77f73Yw==",
"license": "MIT",
"peerDependencies": {
"typescript": ">=5"
diff --git a/package.json b/package.json
index 1416f46..2b8e1bf 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,8 @@
"@radix-ui/react-tooltip": "^1.2.8",
"@radix-ui/react-visually-hidden": "^1.2.4",
"@tanstack/react-query": "^5.8.0",
- "@tma.js/sdk-react": "^3.0.15",
+ "@telegram-apps/react-router-integration": "^1.0.1",
+ "@telegram-apps/sdk-react": "^3.3.9",
"axios": "^1.6.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -45,7 +46,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^13.5.0",
- "react-router-dom": "^7.13.0",
+ "react-router-dom": "^6.30.3",
"tailwind-merge": "^3.4.0",
"zustand": "^4.4.0"
},
diff --git a/src/AppWithNavigator.tsx b/src/AppWithNavigator.tsx
new file mode 100644
index 0000000..fb05276
--- /dev/null
+++ b/src/AppWithNavigator.tsx
@@ -0,0 +1,102 @@
+import { useEffect, useMemo } from 'react';
+import { BrowserRouter, Router } from 'react-router-dom';
+import { useIntegration } from '@telegram-apps/react-router-integration';
+import { initNavigator } from '@telegram-apps/sdk';
+import App from './App';
+import { PlatformProvider } from './platform/PlatformProvider';
+import { ThemeColorsProvider } from './providers/ThemeColorsProvider';
+import { WebSocketProvider } from './providers/WebSocketProvider';
+import { ToastProvider } from './components/Toast';
+import { TooltipProvider } from './components/primitives/Tooltip';
+
+/**
+ * Check if running inside Telegram Mini App
+ * Uses multiple checks to reliably detect Telegram environment
+ */
+function isTelegramMiniApp(): boolean {
+ if (typeof window === 'undefined') return false;
+
+ const webApp = window.Telegram?.WebApp;
+ if (!webApp) return false;
+
+ // Check 1: initDataUnsafe should have user data in real Telegram
+ const hasUserData = webApp.initDataUnsafe?.user?.id !== undefined;
+
+ // Check 2: Platform should not be 'unknown' (which is default in browser)
+ const validPlatform = webApp.platform !== 'unknown' && webApp.platform !== '';
+
+ // Check 3: Version should be present (SDK loads in Telegram only)
+ const hasVersion = webApp.version !== undefined && webApp.version !== '';
+
+ return hasUserData || (validPlatform && hasVersion);
+}
+
+/**
+ * Component wrapper for Telegram navigator setup.
+ * Integrates Telegram Mini Apps navigator with React Router to provide
+ * automatic BackButton management based on navigation history.
+ * Falls back to BrowserRouter when not in Telegram Mini App.
+ */
+/**
+ * Navigator-based router for Telegram Mini App
+ */
+function TelegramRouter({ children }: { children: React.ReactNode }) {
+ const navigator = useMemo(() => initNavigator('app-navigation-state', { hashMode: null }), []);
+ const [location, reactNavigator] = useIntegration(navigator);
+
+ useEffect(() => {
+ try {
+ navigator.attach();
+ return () => {
+ try {
+ navigator.detach();
+ } catch (err) {
+ console.warn('Failed to detach navigator:', err);
+ }
+ };
+ } catch (err) {
+ console.warn('Failed to attach navigator:', err);
+ }
+ }, [navigator]);
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function AppWithNavigator() {
+ const isTelegram = useMemo(() => {
+ const result = isTelegramMiniApp();
+ console.log('[AppWithNavigator] Platform detection:', {
+ isTelegram: result,
+ platform: window.Telegram?.WebApp?.platform,
+ hasUser: window.Telegram?.WebApp?.initDataUnsafe?.user?.id !== undefined,
+ version: window.Telegram?.WebApp?.version,
+ });
+ return result;
+ }, []);
+
+ // Common app content
+ const appContent = (
+
+
+
+
+
+
+
+
+
+
+
+ );
+
+ // Use Telegram navigator in Mini App, BrowserRouter elsewhere
+ if (isTelegram) {
+ return {appContent};
+ }
+
+ return {appContent};
+}
diff --git a/src/main.tsx b/src/main.tsx
index 6897c17..ba8673c 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,13 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
-import { BrowserRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import App from './App';
-import { PlatformProvider } from './platform/PlatformProvider';
-import { ThemeColorsProvider } from './providers/ThemeColorsProvider';
-import { WebSocketProvider } from './providers/WebSocketProvider';
-import { ToastProvider } from './components/Toast';
-import { TooltipProvider } from './components/primitives/Tooltip';
+import { AppWithNavigator } from './AppWithNavigator';
import { initLogoPreload } from './api/branding';
import { initTelegramSDK } from './hooks/useTelegramSDK';
import './i18n';
@@ -31,19 +25,7 @@ const queryClient = new QueryClient({
ReactDOM.createRoot(document.getElementById('root')!).render(
-
-
-
-
-
-
-
-
-
-
-
-
-
+
,
);
diff --git a/src/platform/hooks/useBackButton.ts b/src/platform/hooks/useBackButton.ts
index ec0dcbe..8124fa0 100644
--- a/src/platform/hooks/useBackButton.ts
+++ b/src/platform/hooks/useBackButton.ts
@@ -1,6 +1,3 @@
-import { useEffect, useRef, useCallback } from 'react';
-import { usePlatform } from '@/platform/hooks/usePlatform';
-
interface UseBackButtonOptions {
/**
* Whether the back button should be visible
@@ -11,65 +8,46 @@ interface UseBackButtonOptions {
/**
* Hook to manage the Telegram BackButton
- * Automatically shows/hides based on component lifecycle
*
- * @param onBack - Callback when back button is pressed
- * @param options - Configuration options
+ * NOTE: This hook is now a no-op for backward compatibility.
+ * The Telegram Navigator (@telegram-apps/react-router-integration) handles
+ * BackButton visibility and navigation automatically based on router history.
+ *
+ * The navigator:
+ * - Shows BackButton when there's navigation history
+ * - Hides BackButton on root page
+ * - Handles back button clicks automatically
+ *
+ * @param onBack - (Ignored) Callback when back button is pressed
+ * @param options - (Ignored) Configuration options
*
* @example
* ```tsx
* function MyPage() {
* const navigate = useNavigate();
- * useBackButton(() => navigate(-1));
+ * useBackButton(() => navigate('/admin')); // No-op: navigator handles this
* // ...
* }
* ```
*/
export function useBackButton(
- onBack: (() => void) | null | undefined,
- options: UseBackButtonOptions = {},
+ _onBack: (() => void) | null | undefined,
+ _options: UseBackButtonOptions = {},
): void {
- const { backButton, capabilities } = usePlatform();
- const { visible = true } = options;
-
- // Use ref to prevent callback recreation issues
- const callbackRef = useRef(onBack);
- callbackRef.current = onBack;
-
- // Stable callback wrapper
- const handleBack = useCallback(() => {
- callbackRef.current?.();
- }, []);
-
- useEffect(() => {
- // If no native back button support, do nothing
- if (!capabilities.hasBackButton) {
- return;
- }
-
- // If callback is null/undefined or visible is false, hide button
- if (!onBack || !visible) {
- backButton.hide();
- return;
- }
-
- // Show the back button with our handler
- backButton.show(handleBack);
-
- // Cleanup: hide button when component unmounts
- return () => {
- backButton.hide();
- };
- }, [backButton, capabilities.hasBackButton, handleBack, onBack, visible]);
+ // No-op: Navigator handles BackButton automatically
+ return;
}
/**
* Hook to conditionally show back button based on navigation depth
- * Useful for showing back button only when there's history to go back to
*
- * @param canGoBack - Whether navigation back is possible
- * @param onBack - Callback when back button is pressed
+ * NOTE: This hook is now a no-op for backward compatibility.
+ * The navigator handles conditional visibility automatically.
+ *
+ * @param canGoBack - (Ignored) Whether navigation back is possible
+ * @param onBack - (Ignored) Callback when back button is pressed
*/
-export function useConditionalBackButton(canGoBack: boolean, onBack: () => void): void {
- useBackButton(canGoBack ? onBack : null);
+export function useConditionalBackButton(_canGoBack: boolean, _onBack: () => void): void {
+ // No-op: Navigator handles BackButton automatically
+ return;
}
diff --git a/vite.config.ts b/vite.config.ts
index 0420b8d..9d07f2e 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -49,7 +49,11 @@ export default defineConfig({
'@radix-ui/react-visually-hidden',
],
'vendor-dnd': ['@dnd-kit/core', '@dnd-kit/sortable', '@dnd-kit/utilities'],
- 'vendor-telegram': ['@tma.js/sdk-react'],
+ 'vendor-telegram': [
+ '@telegram-apps/sdk',
+ '@telegram-apps/sdk-react',
+ '@telegram-apps/react-router-integration',
+ ],
'vendor-utils': [
'axios',
'zustand',