Skip to content
jlongyamPublic

About

A hash based router

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Router

A hash based Router

npm version CI npmx

But why?

The the difference of this router with other hash router is have ability to parse sub slash after query,

example

#page/test?asset=/path/to/file.js

That slash after querty parsed properly.

Features

  • simple -> focuc to hash only
  • small -> under 100 lines of code
  • query friedly -> explained above
  • typed -> ships its own type definitions, no @types/* needed
  • ready to use -> import router from '@jlbyte/router', no new Router()
  • router.match -> work in node and browser
  • router.route -> work in browser

Usage

Design site map

Import

import router from '@jlbyte/router'
  1. Basic design
console.dir( router.match('#index', ':page') );
{ path: 'index', params: { page: 'index' }, query: {} }
  1. Complex design
console.dir( router.match('#page/test?asset=path/to/file.js', 'page/:any') );
{
  path: 'page/test',
  params: { '$0': 'test' },
  query: { asset: 'path/to/file.js' }
}

See usage detail in usage/design.mjs

Test design

Example:

let hash = '#lib/test/src?path=./root/file.css'
let pattern = 'lib/:n/src' 
 

let result = { 
  path: 'lib/test/src',
  params: { n: 'test' },
  query: { path: './root/file.css' }
}

console.assert( router.match( hash, pattern ), result )
Create route

Design:

console.dir( router.match('#style/load?file=style.css', 'style/:action') )

Result:

{
  path: 'style/load',
  params: { action: 'load' },
  query: { file: 'style.css' }
}

Implementation:

router.route('style/:action', ({ params, query })=> {
  if(params.action === 'load') {
    console.log( query.file )
  }
})
Manage Navigation

Example:

router.navigate('#style/load?file=style.css')

See usage detail in usage/route.mjs

Pretty URL

How to create pretty URL like https://example.com/#/other/page

  1. Design first
console.log( 'Design', router.match('#/other', '/:page') );
  1. Catch route
router.route('/:page', ({params})=> {
  console.log('Routes: ', params);
}
  1. Test
router.navigate('#/other');

See usage/pretty.html for example

Format

TypeScript

Type definitions are bundled, so editors and tsc pick them up without installing anything extra:

import router from '@jlbyte/router'
import type { MatchResult, RouteMatch } from '@jlbyte/router'

const parsed: MatchResult | null = router.match('#page/test', 'page/:any')
Javascript

Two entry points:

  • import -> src/router.mjs, native ESM shipped as source (no build). Its single default export is the ready-made router.
  • <script> -> dist/router.js, an IIFE that registers window.router automatically (the Router class is not exposed globally).
<script src="https://cdn.jsdelivr.net/npm/@jlbyte/router/dist/router.js"></script>
<script>
  router.route(':page', ({ params }) => console.log(params.page))
  router.navigate('#home')
</script>

No wiring is needed with the script tag: router is already global.

Legacy

dist/router.legacy.js is the same router transpiled to ES5, for engines that predate ES2015.

It is standalone, the few runtime APIs it needs

  • Map,
  • Symbol.iterator,
  • Object.entries,
  • Array.from and
  • String.prototype.startsWith

are shipped as small guarded shims inside the file, so no polyfill file has to be loaded first.

<script src="https://cdn.jsdelivr.net/npm/@jlbyte/router/dist/router.legacy.js"></script>
<script>
  router.route(':page', function (result) {
    console.log(result.params.page)
  })
</script>

If your page already provides those APIs, the shims detect them and do nothing. Only the syntax is ES5; write the code that uses the router in ES5 too when targeting those browsers.

dist/ is generated by pnpm build (rollup) and is not committed.

Development

  • Node 20 is the minimum (engines.node: ">=20")
  • Development runs on Node 26 (.nvmrc)
  • CI checks both: 20 for the floor, 26 for the current runtime
nvm use 
pnpm install
pnpm test
pnpm typecheck
pnpm build
pnpm test:webkit
  • To exercise the 32-bit / legacy path locally, switch down: nvm use 20.20.0

  • NW.js is a devDependency for manual desktop checks (pnpm usage:nw)

pnpm approve-builds
pnpm usage:nw
  • CI installs with --ignore-scripts, so that download never runs on GitHub.

Similiar projects

Similiar project that using hash router

Acknowledgments

The resources you find helpful and would like to give credit to

Roadmap

  • create legacy compability script
  • usage for pretty URL
  • create custom HTML element <ux-router>

License

Distributed under the MIT License.

About

A hash based router

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages