Skip to content

Latest commit

 

History

History
134 lines (114 loc) · 3.35 KB

overview.md

File metadata and controls

134 lines (114 loc) · 3.35 KB

Overview

little-router was inspired by the route configuration used by react-router, and the middleware pattern implemented by frameworks such as Express or Koa. It was built to be flexible enough to support both static route matching, as well as asynchronous route resolution.

Route Config

Routes are declared as an array of plain objects. Each route object can take any desired shape, with the exception of a few special properties used by the router. One such property is path, which indicates the URL path to use when matching the route (using the path-to-regexp library).

const routes = [
  {
    path: '/',
    name: 'home',
  },
  {
    path: '/about',
    name: 'about',
  }
]

Nested Routes

Each route can optionally specify a routes property to list child routes.

const routes = [
  {
    path: '/admin',
    routes: [
      {
        path: '/',
        name: 'dashboard',
      },
      {
        path: '/users',
        name: 'users'
      }
    ]
  }
]

Route Matching

The router traverses the route configuration array until a route is matched against the provided path. If a match is found, a result object containing the matched route is returned, else undefined.

import { match } from 'little-router'

const routes = [
  { path: '/about', name: 'about' }
]

const result = match({ routes, path: '/about' })
// => { route: { name: 'about' } }

Named Parameters

Captured named route parameters are also returned in the result object.

import { match } from 'little-router'

const routes = [
  { path: '/:slug', name: 'page' }
]

const result = match({ routes, path: '/about' })
// => { route: { name: 'page' }, params: { slug: 'about' } }

Route Resolution

Routes can specify a resolve function to asynchronously resolve the route. The function is passed a context argument containing the static route object, and named parameters.

import { match } from 'little-router'
import { fetchContent } from './fetchContent'

const routes = [
  {
    path: '/about',
    name: 'about',
    resolve: async ({ route, params }) => ({
      ...route,
      component: import(`./components/About`),
    }),
  }
]

const result = await match({ routes, path: '/about' })
// => { route: { name: 'about', component: About } }

Route Context

Arbitrary data can be passed to the route.resolve() method via the context option.

import { match } from 'little-router'

const routes = [{
  path: '/admin',
  resolve: ({ route, admin }) => {
    if (!admin) {
      throw new Error('Unauthorized!')
    }
    return route
  }
}]

match({
  routes,
  path: '/admin',
  context: {
    admin: true,
  }
})

Middleware

Parent routes that define a resolve function are responsible for resolving child routes by calling a middleware style next() function provided by the context argument.

import { match } from 'little-router'

const routes = [{
  path: '/admin',
  resolve: ({ route, next }) => {
    return {
      layout: 'default',
      ...next(),
    }
  },
  routes: [{
    path: '/',
    view: 'dashboard',
  }]
}]

const result = match({ routes, path: '/admin' })
// => { route: { layout: 'default', view: 'dashboard' } }