Declarative Routes with Universal Router

by shriek

HTML

<script src="https://unpkg.com/[email protected]/universal-router.min.js"></script>
<script src="https://unpkg.com/react@15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
<div id="app"></div>

Babel + JSX

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

// Page Components
class Login extends React.Component {
  render() { return <h1>Login Component</h1> }
}
class Admin extends React.Component {
  render() { return <h1>Admin Component</h1> }
}
class Users extends React.Component {
  render() { return (
    <div>
      <h1>Users Component</h1>
      <pre>{this.props.data}</pre>
    </div>
  ) }
}

// Declarative Routes
const routes = [
  {
    path: '/login',
    title: 'Login Page',
    component: Login,
  },
  {
    path: '/admin',
    protected: true,
    children: [
      {
        path: '/',
        title: 'Admin Page',
        component: Admin
      },
      {
        path: '/users',
        title: 'Users Page',
        api: '/api/users',
        component: Users
      },
    ],
  },
];

function resolveRoute(context) {
  if (context.route.protected && !context.isAdmin) {
    return { redirect: '/login' };
  }

  if (context.route.api) {
    return fetch(context.route.api).then(resp => resp.text()).then(data =>
      Object.assign({ data }, context.route)
    );
  }

  if (context.route.component) {
    return context.route;
  }
}

const context = { isAdmin: true };
const container = document.getElementById('app');
const router = new UniversalRouter(routes, { context, resolveRoute });

router.resolve('/admin').then(result => {
  if (result.redirect) {
    console.log('redirect to', result.redirect);
    return;
  }

  document.title = result.title;
  ReactDOM.render(<result.component data={result.data} />, container);
});