Skip to content

Instantly share code, notes, and snippets.

@abradley2
Created May 28, 2018 13:20
Show Gist options
  • Save abradley2/1baa9102969e052f14a02b621fa57b53 to your computer and use it in GitHub Desktop.
Save abradley2/1baa9102969e052f14a02b621fa57b53 to your computer and use it in GitHub Desktop.
Routing in vanilla.js
// first we need to intercept all clicks on our "spa-links" so they don't trigger a page reload.
// we can then use `history.pushState` so those link clicks still change the url appropriately.
// we will use the "spa-link" attribute to specify links in our application we want to intercept the clicks
// to, so we don't break links that go to external sites other than our spa.
// for example: <a href="/in-our-spa" spa-link>Link in our SPA!</a>
document.addEventListener('click', (e) => {
if (e.target.getAttribute('spa-link')) {
e.preventDefault()
history.pushState(null, document.title, e.target.getAttribute('href'))
handleNavigation()
}
})
// next we need to subscribe to "popstate" which let's us know when the user has clicked the
// "back" or "forward" button on their browser
window.addEventListener('popstate', handleNavigation)
// now our handleNavigation callback is reliably fired whenever we need to react to a
// a SPA navigation action. We can define it however we want.
function handleNavigation() {
const path = window.location.pathname
// now we want to take the path and do something based on it.
// at the MOST basic level we choose a function to perform based on the path
function notFound() {
...
}
const route = {
'/home': () => { ... },
'/about': () => { ... }
}[path] || notFound
// what you actually do in any of those function is dependent on your SPA
// but at the base level that's it. Routing is just mapping a url to an associated
// function that you trigger.
// for more complex spa's you'll want to allow regexes and wildcards to turn into
// parameters you pass to those functions.
// libraries like pathToRegExp are nice for this
// https://www.npmjs.com/package/path-to-regexp
// but there's many other ways as well. Just look around and use what you like best.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment