История и хост
Мини-апп живёт в iframe webview: у него нет собственной адресной строки, а «назад» — это системный жест или кнопка хоста. Пакет берёт на себя три вещи: где хранить URL, как сообщать его хосту и когда включать нативный swipe-back.
Режимы истории
Заголовок раздела «Режимы истории»createVkHistory из core-слоя:
createVkHistory(); // "hash" (дефолт): #/meeting/7createVkHistory({ mode: "hash-param" }); // #?path=/meeting/7// "browser": опусти history в createRouter — TanStack возьмёт своюhash— хэш и есть локация. Актуально, когда хост не даёт управлять path.hash-param— путь ездит в hash-параметреpath(имя меняется черезpathParam). Чужие hash-параметры сохраняются,location.searchне трогается.browser— обычная история браузера; просто не передавайhistoryвcreateRouter.
Глубокая ссылка, написанная в другом режиме, тоже разрешается (легаси-толерантность) — старые рассылки не ломаются. История построена на createBrowserHistory TanStack — блокеры и popstate работают как в обычном TanStack.
Синхронизация с хостом
Заголовок раздела «Синхронизация с хостом»createBridgeSync связывает историю и хост в обе стороны:
import { createBridgeSync } from "@vkma.dev/router";
createBridgeSync({ history: router.history, bridge });- Каждый зафиксированный шаг истории отправляется хосту как
VKWebAppSetLocationсreplace_state: true— URL шеринга и кнопка «назад» хоста отражают состояние приложения. Локация старта отправляется один раз при создании. - Входящие
VKWebAppChangeFragmentиVKWebAppLocationChanged(прыжок, инициированный хостом) превращаются вhistory.replace(href). Эхо собственной локации игнорируется — цикл не возникает. - «Назад» хоста — это территория
VKWebAppClose: ChangeFragment не является pop’ом фрагмента.
Кодеки payload зависят от режима: hash отправляет содержимое хэша, hash-param — ?path=… с сохранением чужих параметров. Вызывай sync после создания роутера (не в module scope рядом с его объявлением) — иначе цикл модулей падает с TDZ.
Swipe-back
Заголовок раздела «Swipe-back»createSwipeBackManager управляет нативным жестом:
import { createSwipeBackManager } from "@vkma.dev/router";
createSwipeBackManager({ history: router.history, bridge });Автоматическое правило: жест включён, пока приложение может вернуться в своей истории, и выключен на первой записи — там системный «назад» должен закрывать приложение. Реализация шлёт VKWebAppSetSwipeSettings { history } плюс VKWebAppEnableSwipeBack/VKWebAppDisableSwipeBack; ошибка с кодом 6 на вебе заглушена.
Полный отказ (приложение само управляет жестом): createSwipeBackManager({ enabled: false }) — жёсткий opt-out, побеждающий всё ниже.
Точечный override в панели
Заголовок раздела «Точечный override в панели»useEnableSwipeBack(false, panel);Передай false для поверхностей, где жест мешает (рисование, drag), и обязательно второй аргумент — хэндл панели. Панели — вечно смонтированные статические дети: без привязки override прилипнет к той панели, что смонтировалась последней, а с ref он действует только пока эта панель — глубже всех сматченная, и отпускается при уходе. true форсирует жест даже на первой записи — системный «назад» тогда закрывает приложение.
Оверлеи поверх истории — в модалках и popout’ах.