SPA: UniversalRouter + React

HTML

<script src="https://unpkg.com/react@15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
<script src="https://unpkg.com/universal-router@3/universal-router.js"></script>
<div id="app"></div>
<div id="output"></div>

Babel + JSX

// import React from 'react'
// import ReactDOM from 'react-dom'
// import UniversalRouter from 'universal-router'

const container = document.getElementById('app')
const output = document.getElementById('output')

// universal (isomorphic) component
const Nav = () =>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/users">Users</a></li>
    <li><a href="/user/456">User #456</a></li>
    <li><a href="/user/789?query=and#hash-example">User #789</a></li>
  </ul>

// universal (isomorphic) routing
const router = new UniversalRouter([
  { path: '/', action: () => (
    <div>
      <h1>Home</h1>
      <Nav />
    </div>
  ) },
  { path: '/users', action: () => (
    <div>
      <h1>Users</h1>
      <Nav />
    </div>
  ) },
  { path: '/user/:id', action: (context) => (
    <div>
      <h1>User #{context.params.id}</h1>
      <Nav />
    </div>
  ) }
])

// client-side renering
async function render() {
  output.innerText = `Current location: ${
    location.pathname}${
    location.search}${
    location.hash}`

  const page = await router.resolve(location.pathname)
  ReactDOM.render(page, container)
}
 
// single page application
window.addEventListener('click', event => {
  if (event.target.tagName === 'A') {
    event.preventDefault()
    const anchor = event.target
    const state = null
    const title = anchor.textContent
    const url = anchor.pathname + anchor.search + anchor.hash
    history.pushState(state, title, url)
    render()
  }
})

// launch the app
history.replaceState(null, '', '/') // jsfiddle hack: redirect to the home page
render()