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

@riogz/router-plugin-browser

v1.0.5

Published

Browser plugin for @riogz/router integration with browser history

Downloads

15

Readme

@riogz/router-plugin-browser

Browser integration plugin for @riogz/router. Provides seamless integration between the router and browser navigation, supporting both HTML5 history API and hash-based routing.

Features

  • HTML5 History API Support - Modern pushState/replaceState navigation
  • Hash-based Routing - Fallback for older browsers or specific requirements
  • Base Path Support - Deploy apps in subdirectories
  • State Preservation - Maintain router state in browser history
  • SSR Compatible - Safe fallbacks for server-side rendering
  • TypeScript Support - Full type definitions included

Installation

npm install @riogz/router-plugin-browser

Basic Usage

import { createRouter } from '@riogz/router'
import browserPlugin from '@riogz/router-plugin-browser'

const routes = [
  { name: 'home', path: '/' },
  { name: 'users', path: '/users/:id' }
]

const router = createRouter(routes)

// Use the browser plugin
router.usePlugin(browserPlugin())

// Start the router
router.start()

Configuration Options

BrowserPluginOptions

interface BrowserPluginOptions {
  forceDeactivate?: boolean    // Force route deactivation during transitions (default: true)
  useHash?: boolean           // Use hash-based routing (default: false)
  hashPrefix?: string         // Prefix after hash symbol (default: '')
  base?: string | null        // Base path for the application (default: '')
  mergeState?: boolean        // Merge with existing browser state (default: false)
  preserveHash?: boolean      // Preserve URL hash during navigation (default: true)
}

Usage Examples

HTML5 History Mode (Default)

// URLs: /users/123, /profile, /settings
router.usePlugin(browserPlugin({
  useHash: false
}))

Hash-based Routing

// URLs: #/users/123, #/profile, #/settings
router.usePlugin(browserPlugin({
  useHash: true
}))

// With prefix: #!/users/123, #!/profile, #!/settings
router.usePlugin(browserPlugin({
  useHash: true,
  hashPrefix: '!'
}))

Application in Subdirectory

// URLs: /myapp/users/123, /myapp/profile
router.usePlugin(browserPlugin({
  base: '/myapp'
}))

State Merging

// Preserve additional properties in history.state
router.usePlugin(browserPlugin({
  mergeState: true
}))

// Now you can add custom data to history
history.replaceState({
  ...history.state,
  scrollPosition: window.scrollY,
  customData: 'value'
}, '', location.href)

Extended Router Methods

The plugin adds several methods to the router instance:

buildUrl(name, params)

Build a complete URL for a route:

// With base path and hash prefix
const url = router.buildUrl('users.profile', { id: '123' })
// Result: /myapp#!/users/123/profile (depending on config)

matchUrl(url)

Match a complete URL against routes:

const state = router.matchUrl('https://example.com/users/123')
if (state) {
  console.log(state.name)   // 'users'
  console.log(state.params) // { id: '123' }
}

replaceHistoryState(name, params, title)

Update browser history without navigation:

// Update URL and history state without triggering route change
router.replaceHistoryState('users.profile', { id: '456' }, 'User Profile')

Browser Abstraction

The plugin uses a browser abstraction layer that provides safe fallbacks for non-browser environments:

import browser from '@riogz/router-plugin-browser/browser'

// Safe to use in any environment
const currentPath = browser.getLocation({ useHash: false, base: '' })
browser.pushState({ name: 'home' }, 'Home', '/home')

Testing

For testing, you can provide a mock browser implementation:

import browserPlugin from '@riogz/router-plugin-browser'

const mockBrowser = {
  getBase: () => '/test',
  pushState: jest.fn(),
  replaceState: jest.fn(),
  addPopstateListener: jest.fn(() => () => {}),
  getLocation: () => '/current/path',
  getState: () => null,
  getHash: () => ''
}

router.usePlugin(browserPlugin({}, mockBrowser))

Advanced Configuration

Custom Hash Prefix

// Google-style hash routing: #!/users/123
router.usePlugin(browserPlugin({
  useHash: true,
  hashPrefix: '!'
}))

Preserve Hash Fragments

// Maintain #section anchors during navigation
router.usePlugin(browserPlugin({
  preserveHash: true  // default
}))

// Navigate from /page1#section1 to /page2#section1
router.navigate('page2')

Force Route Deactivation

// Control route lifecycle during transitions
router.usePlugin(browserPlugin({
  forceDeactivate: false  // Allow routes to stay active when possible
}))

Browser Compatibility

  • Modern Browsers: Full HTML5 history API support
  • Legacy Browsers: Automatic fallback to hash-based routing
  • Internet Explorer: Special handling for hashchange events
  • Server-Side Rendering: Safe no-op implementations

Error Handling

The plugin handles various error scenarios:

  • Navigation Blocking: Respects route guards and canDeactivate hooks
  • Invalid URLs: Graceful fallback to default routes
  • State Conflicts: Prevents duplicate history entries
  • Browser Limitations: Automatic detection and workarounds

Integration with Other Plugins

The browser plugin works seamlessly with other router plugins:

import browserPlugin from '@riogz/router-plugin-browser'
import loggerPlugin from '@riogz/router-plugin-logger'

router.usePlugin(browserPlugin())
router.usePlugin(loggerPlugin())

TypeScript Support

Full TypeScript definitions are included:

import { BrowserPluginOptions, Browser, HistoryState } from '@riogz/router-plugin-browser'

const options: BrowserPluginOptions = {
  useHash: true,
  hashPrefix: '!'
}

const customBrowser: Browser = {
  // Implementation
}

API Reference

Types

  • BrowserPluginOptions - Configuration options for the plugin
  • Browser - Browser abstraction interface
  • HistoryState - Extended router state with browser history data

Functions

  • browserPluginFactory(options?, browser?) - Create a browser plugin instance
  • default export - The browserPluginFactory function

License

MIT © Vyacheslav Krasnyanskiy