router
@vkma.dev/router — роутер для VK Mini Apps поверх TanStack Router. Вьюхи, панели, модалки и popout’ы управляются URL и рендерятся хостами VKUI: типизированные хэндлы вместо строковых id, синхронизация с VK-историей и хостом (VKWebAppSetLocation, VKWebAppChangeFragment), управление swipe-back. Feature parity с @vkontakte/vk-mini-apps-router, но не API parity.
npm install @vkma.dev/router @tanstack/react-router# peers: @tanstack/react-router ^1.170, @vkontakte/vkui ^8 (опционально), react ^18 | ^19Объявление вьюх
Заголовок раздела «Объявление вьюх»// panels/profile/profile.panel.ts — единственное место, где пишется ключ "profile"import { defineView } from "@vkma.dev/router/preset";
export const profileView = defineView("profile");
// "index" владеет "/", "$id" объявляет типизированный path-параметрexport const profilePanel = profileView.panel("index", {}, () => import("./profile.ui"));export const profileSettingsPanel = profileView.panel( "settings", { // loaders выполняются до монтирования панели; читаешь через usePanelLoaderData(profilePanel) loader: async () => ({ user: await bridge.send("VKWebAppGetUserInfo") }), }, () => import("./profile.ui"),);Приложение и роутер
Заголовок раздела «Приложение и роутер»import { createRouter } from "@tanstack/react-router";// app.tsx, дерево приложения + роутерimport { createApp, AppRootShell } from "@vkma.dev/router/preset";
export const app = createApp({ root: AppRootShell, // или свой шелл (Epic/Tabbar, SplitCol sidebar…) views: [profileView /* … */], modals: {/* keyed entries */}, popouts: {/* keyed entries */},});
export const router = createRouter({ routeTree: app.routeTree, history: createVkHistory({ mode: "hash" }).history, // или "hash-param" defaultNotFoundComponent: NotFound,});
declare module "@tanstack/react-router" { interface Register { router: typeof router; }}VK-история
Заголовок раздела «VK-история»Два режима (по умолчанию "hash"): хэш и есть локация (#/item/7) или hash-param (#?path=… — чужие hash-параметры сохраняются, location.search не трогается). Глубокие ссылки, написанные в другом режиме, тоже разрешаются. Режим "browser" — дефолтная история TanStack.
Разделы
Заголовок раздела «Разделы»- Концепции — URL-driven модель, слои, freeze-семантика хуков.
- Вьюхи и панели —
defineView, порядок анимаций, лоадеры. - Модалки и popout’ы — оверлеи как маршруты.
- История и хост — режимы URL,
VKWebAppSetLocation, swipe-back. - Миграция с vk-mini-apps-router — маппинг API.