3.9 KiB
Native Vue Router
Native Vue Router is a gesture-first navigation runtime for Vue 3 and Vue Router 5. It keeps Vue Router in charge of matching, URLs, guards, and history while rendering live route stacks that can be manipulated interactively.
The repository includes a reusable headless core, a platform-adaptive visual preset, Capacitor and Electron adapters, and one messaging demo delivered as a PWA and through native hosts.
What works
- Interactive edge pop that can be held indefinitely at any progress.
- Ordered horizontal route paging with replace-by-default history.
- Component-originated route dragging with a live target route.
- Interactive push, adjacent-page sibling slide, modal, sheet, fade, and application-defined presentations.
- Concurrent
fromandtoroutes using only public Vue Router 5 APIs. - Guarded commits: previews do not alter the URL, and rejected navigation springs back.
- Cold-start predictive back through declared parent routes.
- Bounded live view caching, nested router views, focus isolation, RTL, and reduced motion.
- PWA, Electron, and Capacitor iOS/Android hosts.
Run it
npm install
npm run dev
The default app is the installable messaging PWA. Other useful commands:
npm run build # packages, declarations, demo, and service worker
npm test # core transaction tests
npm run test:e2e # desktop and mobile Playwright projects
npm run electron # build and launch the Electron host
npm run cap:sync # build and synchronize iOS and Android projects
Native projects live under apps/capacitor/ios and apps/capacitor/android. Open or run them from apps/capacitor with npx cap open ios, npx cap open android, or npx cap run <platform>.
Minimal integration
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import { createNativeRouter } from '@native-vue-router/core'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{
path: '/chat/:id',
component: Chat,
meta: {
native: { presentation: 'push', parent: '/', gesture: 'edge' },
},
},
],
})
const nativeRouter = createNativeRouter({ router })
createApp(App).use(router).use(nativeRouter).mount('#app')
<script setup lang="ts">
import { NativeGestureLink, NativeNavigator, NativeRouterView } from '@native-vue-router/core'
</script>
<template>
<NativeNavigator :siblings="['/', '/stories', '/profile']">
<NativeRouterView />
</NativeNavigator>
<NativeGestureLink to="/chat/maya" presentation="reveal">
Drag this row into the chat route
</NativeGestureLink>
</template>
Import @native-vue-router/core/style.css for the built-in presentation layers. The demo imports @native-vue-router/preset-native/style.css as well.
Use nativeRouter.sibling(to) for tab or peer-route navigation. Direction is derived from siblingOrder, repeated navigation to the active route is a no-op, and siblingHistory: 'replace' keeps cached tab views out of the back stack.
Packages
@native-vue-router/core— transactions, route ledger, concurrent views, gestures, caching, and public components/composables.@native-vue-router/preset-native— adaptive tab/back controls, safe-area CSS, and platform motion defaults.@native-vue-router/capacitor— hardware back, deep links, pause cancellation, root exit, and haptics.@native-vue-router/electron— Chromium history-gesture suppression and renderer back/forward bridging.
See architecture and platform integration for the transaction lifecycle and host-specific behavior.
Support contract
The target is Vue 3.5+ and Vue Router 5. Installed PWAs, current Electron, and Capacitor 8 are first-class. Normal browser tabs remain functional but browsers can reserve edge gestures that page content cannot consistently override.
MIT