A very simple dependency-free router written in typescript. You can use it to build lightweight SPAs or enhance your traditional multi page websites.
npm install @very-simple/router
import router from '@very-simple/router'
router.route('/', () => console.log('Home'))
router.route('/about', () => console.log('About'))
router.route('/projects/:id', ({ id }) => console.log(`Show project ${id}`))
router.route('*', () => console.log('Not found!'))
router.start()
<a class="router-link" href="/">Home</a>
<a class="router-link" href="/about">About</a>
<a class="router-link" href="/projects/test">This one project</a>
To prevent the links from actually changing the page we have to intercept the click events and push/replace a route instead.
document.querySelectorAll('a.router-link').forEach((el) =>
el.addEventListener('click', (event) => {
event.preventDefault()
router.push(el.getAttribute('href'))
})
)
router.start(options?)
interface RouterOptions {
// Wether or not to handle the initial route, default is `true`
handleInitial: boolean;
}
router.push('/path/to/something')
router.replace('/path/to/something')
router.route('/path', (params, to, from) => /* Do something ... */)
You can handle the initial route differently (e.g.: no smooth scrolling):
router.route('projects/:id', (params, route) => {
const isInitial = route.trigger === 'init'
const el = document.getElementById(params.id)
el.scrollIntoView({ behavior: isInitial ? 'auto' : 'smooth' })
})
Or differentiate between manual push/replace navigation and the browser's back/forward buttons:
router.route('data/:url', (params, route) => {
const shouldUseCache = route.trigger === 'popstate'
if (shouldUseCache) {
// use cached data
} else {
// fetch new data
}
})
You can use one or more dynamic segments (denoted by a colon :
). The dynamic
segments will then be available in the route's action callback.
const action = (params) => {
console.log(`Hello ${params.firstName} ${params.lastName}!`)
}
router.route('/user/:firstName/:lastName', action)
Use the current route anywhere in your project:
import router from './router.js'
window.addEventListener('click', () => {
if (router.currentRoute.path === '/') {
console.log('Welcome home!')
} else {
console.log(`Welcome ${router.currentRoute.params.name}`)
}
})
You can use the asterisk *
to match any route that is not matched by a
previous route. See important for the asterisk's limitations.
router.route('*', () => console.log('Not found!'))
Execute a callback before or after each route. This are simple hooks, no navigation guards. So you can't use them to redirect or cancel routes. The callbacks receive the new and the previous route.
// Gets called before the to route's action is called.
router.on('before-route', (to, from) => console.log(`Changing to: ${to.path}`))
// Gets called after the to route's action is called.
router.on('route', (to, from) =>
console.log(`Changed to: ${to.path} from: ${from.path}`)
)
- the router uses HTML5 history mode only, so make sure your server is setup correctly (see vue router's explanation).
- The asterisk
*
can only be used to catch all routes. It is not possible to use it like this'/user-*'
.