npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@openwebf/vue-router

v1.0.0

Published

Vue Router implementation for WebF applications using hybrid history API

Readme

@openwebf/vue-router

A Vue Router implementation for WebF applications using hybrid history API. This package provides navigation and routing capabilities specifically designed for WebF's hybrid environment, combining web-like history management with Flutter-like navigation patterns.

Features

  • 🚀 Hybrid Navigation: Seamlessly bridge between WebF's native navigation and Vue's routing
  • 📱 Flutter-like API: Familiar navigation methods like push, pop, popUntil, etc.
  • 🎯 Type-safe Routing: Full TypeScript support with type-safe route parameters
  • Performance Optimized: prerender support and smart component lifecycle management
  • 🔄 State Management: Pass and receive data between routes with ease
  • 📊 Route Context: Access route information anywhere in your component tree

Runtime Requirements (WebF)

This router is designed for the WebF environment and expects:

  • webf.hybridHistory (navigation runtime)
  • <webf-router-link> (route container element that fires onscreen/offscreen and hybridrouterchange)

It is not intended to be used in a normal browser environment.

Installation

npm install @openwebf/vue-router
# or
yarn add @openwebf/vue-router
# or
pnpm add @openwebf/vue-router

Peer Dependencies

This package requires the following peer dependencies:

  • vue >= 3.0.0
  • @openwebf/webf-enterprise-typings >= 0.22.0

Quick Start

<template>
  <div id="app">
    <Routes>
      <Route path="/" :element="HomePage" title="Home" />
      <Route path="/about" :element="AboutPage" title="About" />
      <Route path="/profile" :element="ProfilePage" title="Profile" :prerender="true" />
    </Routes>
  </div>
</template>

<script setup>
import { Routes, Route } from '@openwebf/vue-router';
import HomePage from './pages/HomePage.vue';
import AboutPage from './pages/AboutPage.vue';
import ProfilePage from './pages/ProfilePage.vue';
</script>

Core Components

<Routes>

The container component that wraps all your routes and provides the routing context.

<Routes>
  <!-- Your Route components go here -->
</Routes>

<Route>

Defines a single route in your application.

<Route
  path="/profile"
  :element="ProfilePage"
  title="Profile"
  :prerender="true"
/>

Props

  • path (string, required): The path pattern for this route
  • element (Component | string, required): The component to render when this route is active
  • title (string, optional): Title for the route
  • prerender (boolean, optional): Whether to pre-render this route for better performance
  • theme ('material' | 'cupertino', optional): Forwarded to <webf-router-link>

Composition API

useNavigate()

Returns navigation methods to programmatically navigate between routes.

<script setup>
import { useNavigate } from '@openwebf/vue-router';

const { navigate, pop, canPop, popAndPush } = useNavigate();

const handleLogin = async () => {
  await loginUser();

  // Navigate to dashboard
  navigate('/dashboard');

  // Navigate with state
  navigate('/profile', { state: { from: 'login' } });

  // Replace current route
  navigate('/home', { replace: true });

  // Go back
  navigate(-1);
};

const handleCancel = () => {
  if (canPop()) {
    pop(); // Go back
  } else {
    navigate('/'); // Go to home if can't go back
  }
};
</script>

Navigation Methods

  • navigate(to, options?): Navigate to a route
    • to: string (path) or number (-1 for back)
    • options: { replace?: boolean, state?: any }
  • pop(result?): Go back to the previous route
  • popUntil(path): Pop routes until reaching a specific route
  • popAndPush(path, state?): Pop current route and push a new one
  • pushAndRemoveUntil(newPath, untilPath, state?): Push new route and remove all routes until a specific route
  • canPop(): Check if navigation can go back
  • maybePop(result?): Pop if possible, returns boolean

useLocation()

Returns the current location object with pathname and state.

<script setup>
import { useLocation } from '@openwebf/vue-router';

const location = useLocation();

console.log('Current path:', location.value.pathname);
console.log('Location state:', location.value.state);
console.log('Is active:', location.value.isActive);
</script>

<template>
  <div>
    <h1>Profile Page</h1>
    <p v-if="location.state?.from">
      You came from: {{ location.state.from }}
    </p>
  </div>
</template>

useRouteContext()

Access detailed route context information.

<script setup>
import { computed } from 'vue';
import { useRouteContext } from '@openwebf/vue-router';

const route = useRouteContext();
const userId = computed(() => route.value.routeParams?.id ?? '(missing)');

if (route.value.isActive) {
  console.log('This route is currently active');
  console.log('Active path:', route.value.activePath);
  console.log('Route params:', route.value.routeParams);
  console.log('Route state:', route.value.params);
}
</script>

useParams()

Get route parameters from dynamic routes.

<script setup>
// For route pattern "/user/:userId" and actual path "/user/123"
import { computed } from 'vue';
import { useParams } from '@openwebf/vue-router';

const params = useParams();
console.log(params.value.userId); // "123"
const userId = computed(() => params.value.userId ?? '(missing)');
</script>

<template>
  <div>User ID: {{ userId }}</div>
</template>

useRoutes()

Create routes from a configuration object.

<script setup>
import { useRoutes } from '@openwebf/vue-router';
import { defineComponent } from 'vue';
import HomePage from './pages/HomePage.vue';
import AboutPage from './pages/AboutPage.vue';

const routesVNode = useRoutes([
  { path: '/', element: HomePage, title: 'Home' },
  { path: '/about', element: AboutPage, title: 'About' },
  { path: '/profile', element: 'ProfilePage', prerender: true }, // Registered component name (string)
]);

const RoutesView = defineComponent({
  name: 'RoutesView',
  setup() {
    return () => routesVNode;
  },
});
</script>

<template>
  <RoutesView />
</template>

Advanced Usage

Dynamic Routes

Support for route parameters like React Router:

<template>
  <Routes>
    <Route path="/user/:userId" :element="UserPage" />
    <Route path="/posts/:postId/comments/:commentId" :element="CommentPage" />
  </Routes>
</template>

<script setup>
// In UserPage component
import { useParams } from '@openwebf/vue-router';

const params = useParams(); // computed ref
// Access params.value.userId in script, or params.userId in template
</script>

Wildcard Routes

<Routes>
  <Route path="/files/*" :element="FilesPage" />
</Routes>

<script setup>
import { computed } from 'vue';
import { useParams } from '@openwebf/vue-router';

const params = useParams();
const splat = computed(() => params.value['*'] ?? '(missing)');
</script>

Passing State Between Routes

<script setup>
// Navigate with state
const { navigate } = useNavigate();
navigate('/details', {
  state: {
    productId: 123,
    from: 'catalog'
  }
});

// Access state in the target component
const location = useLocation();
const { productId, from } = location.value.state || {};
</script>

Pre-rendering Routes

Pre-rendering improves performance by rendering routes before they're navigated to:

<Routes>
  <Route path="/" :element="Home" />
  <Route path="/dashboard" :element="Dashboard" :prerender="true" />
  <Route path="/profile" :element="Profile" :prerender="true" />
</Routes>

Programmatic Navigation Patterns

<script setup>
const nav = useNavigate();

// Simple navigation
const goToHome = () => nav.navigate('/');

// Replace current entry
const replaceWithLogin = () => nav.navigate('/login', { replace: true });

// Navigate with complex state
const goToProduct = (product) => {
  nav.navigate(`/products/${product.id}`, {
    state: {
      product,
      timestamp: Date.now()
    }
  });
};

// Complex navigation flow
const completeCheckout = async () => {
  // Process payment...
  await processPayment();

  // Go to success page and prevent going back to checkout
  await nav.pushAndRemoveUntil('/success', '/');
};

// Conditional navigation
const smartBack = () => {
  if (nav.canPop()) {
    nav.pop();
  } else {
    nav.navigate('/');
  }
};
</script>

WebF Router API

The package exports a WebFRouter object that provides low-level access to the routing system:

import { WebFRouter } from '@openwebf/vue-router';

// Get current route info
console.log('Current path:', WebFRouter.path);
console.log('Current state:', WebFRouter.state);

// Navigation methods
WebFRouter.push('/new-route', { data: 'value' });
WebFRouter.replace('/replacement-route');
WebFRouter.back();
WebFRouter.pop();
WebFRouter.popUntil('/target');

TypeScript Support

This package is written in TypeScript and provides complete type definitions:

import { useNavigate, useLocation } from '@openwebf/vue-router';
import type { NavigateOptions, Location } from '@openwebf/vue-router';

interface ProfileState {
  userId: string;
  referrer?: string;
}

// Navigate with typed state
const { navigate } = useNavigate();
navigate('/profile', {
  state: {
    userId: '123',
    referrer: 'dashboard'
  } as ProfileState
});

// Access typed state
const location = useLocation();
const state = location.value.state as ProfileState | undefined;

if (state?.userId) {
  // TypeScript knows state.userId is a string
}

Best Practices

  1. Use Pre-rendering for Heavy Components: Enable prerender for routes with expensive initial renders
  2. Clean Up State: Be mindful of state passed between routes, especially for sensitive data
  3. Handle Missing State: Always provide fallbacks when accessing route state
  4. Use Type Safety: Leverage TypeScript for route paths and state objects
  5. Component Types: element can be a Vue component, or a registered component name string

Migration from Vue Router

If you're migrating from standard Vue Router, here are the key differences:

  1. Navigation API: Use navigate() instead of router.push()
  2. Route State: State is passed differently and accessed via useLocation()
  3. No Nested Routes: Current version doesn't support nested routes
  4. Flutter-like Methods: Additional navigation methods like popUntil, popAndPush
  5. Component Structure: Use <Routes> and <Route> instead of <router-view>

Examples

In this repo, a runnable demo app lives at vue_usecases/.

Basic Setup

<template>
  <div id="app">
    <Routes>
      <Route path="/" :element="HomePage" title="Home" />
      <Route path="/about" :element="AboutPage" title="About" />
      <Route path="/contact" :element="ContactPage" title="Contact" />
    </Routes>
  </div>
</template>

<script setup>
import { Routes, Route } from '@openwebf/vue-router';
import HomePage from './pages/HomePage.vue';
import AboutPage from './pages/AboutPage.vue';
import ContactPage from './pages/ContactPage.vue';
</script>

Navigation Component

<template>
  <nav>
    <button @click="() => navigate('/')">Home</button>
    <button @click="() => navigate('/about')">About</button>
    <button @click="() => navigate('/contact')">Contact</button>
  </nav>
</template>

<script setup>
import { useNavigate } from '@openwebf/vue-router';

const { navigate } = useNavigate();
</script>

Troubleshooting

Enable router debug logs

Set a global flag early (before creating your Vue app):

// @ts-ignore
globalThis.__WEBF_VUE_ROUTER_DEBUG__ = true;

When enabled, the router logs include hybridrouterchange:*, routes:sync, and routes:activePathDecision.

Routes not updating

Ensure your Routes component is at the root of your component tree and not inside any conditional rendering.

State is undefined

Route state is only available when navigating TO a route. It's not persisted across page refreshes in WebF.

Performance issues

Enable prerender for routes that take time to render initially.

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

License

Apache-2.0 License. See LICENSE for details.