Coder Social home page Coder Social logo

kriasoft / universal-router Goto Github PK

View Code? Open in Web Editor NEW
1.7K 25.0 106.0 1.62 MB

A simple middleware-style router for isomorphic JavaScript web apps

Home Page: https://www.kriasoft.com/universal-router/

License: MIT License

JavaScript 8.20% TypeScript 91.80%
react reactjs routing router routes spa single-page-app ssr server-side-rendering vuejs

universal-router's Introduction

Universal Router

NPM version NPM downloads Library Size Online Chat

Visit Universal Router Website

A simple middleware-style router that can be used in both client-side and server-side applications.

Visit Quickstart Guide (slides)  |  Join #universal-router on Gitter to stay up to date

Features

What users say about Universal Router

Just switched a project over to universal-router. Love that the whole thing is a few hundred lines of flexible, easy-to-read code.

-- Tweet by Greg Hurrell from Facebook

It does a great job at trying to be universal — it's not tied to any framework, it can be run on both server and client, and it's not even tied to history. It's a great library which does one thing: routing.

-- Comment on Reddit by @everdimension

Installation

Using npm:

npm install universal-router --save

Or using a CDN like unpkg.com or jsDelivr with the following script tag:

<script src="https://unpkg.com/universal-router/universal-router.min.js"></script>

You can find the library in window.UniversalRouter.

How does it look like?

import UniversalRouter from 'universal-router'

const routes = [
  {
    path: '', // optional
    action: () => `<h1>Home</h1>`
  },
  {
    path: '/posts',
    action: () => console.log('checking child routes for /posts'),
    children: [
      {
        path: '', // optional, matches both "/posts" and "/posts/"
        action: () => `<h1>Posts</h1>`
      },
      {
        path: '/:id',
        action: (context) => `<h1>Post #${context.params.id}</h1>`
      }
    ]
  }
]

const router = new UniversalRouter(routes)

router.resolve('/posts').then(html => {
  document.body.innerHTML = html // renders: <h1>Posts</h1>
})

Play with an example on JSFiddle, CodePen, JS Bin in your browser or try RunKit node.js playground.

Documentation

Books and Tutorials

Browser Support

We support all ES5-compliant browsers, including Internet Explorer 9 and above, but depending on your target browsers you may need to include polyfills for Map, Promise and Object.assign before any other code.

For compatibility with older browsers you may also need to include polyfills for Array.isArray and Object.create.

Contributing

Anyone and everyone is welcome to contribute to this project. The best way to start is by checking our open issues, submit a bug report or feature request, participate in discussions, upvote or downvote the issues you like or dislike, send pull requests.

Support

Related Projects

  • React Starter Kit — Boilerplate and tooling for building isomorphic web apps with React and Relay.
  • Node.js API Starter Kit — Boilerplate and tooling for building data APIs with Docker, Node.js and GraphQL.
  • ASP.NET Core Starter Kit — Cross-platform single-page application boilerplate (ASP.NET Core, React, Redux).
  • Babel Starter Kit — Boilerplate for authoring JavaScript/React.js libraries.
  • React App SDK — Create React apps with just a single dev dependency and zero configuration.
  • React Static Boilerplate — Single-page application (SPA) starter kit (React, Redux, Webpack, Firebase).
  • History — HTML5 History API wrapper library that handle navigation in single-page apps.
  • Redux-First Routing — A minimal, framework-agnostic API for accomplishing Redux-first routing.

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

License

Copyright © 2015-present Kriasoft. This source code is licensed under the MIT license found in the LICENSE.txt file. The documentation to the project is licensed under the CC BY-SA 4.0 license.


Made with ♥ by Konstantin Tarkus (@koistya, blog), Vladimir Kutepov and contributors

universal-router's People

Contributors

b-gran avatar dependabot-preview[bot] avatar dependabot[bot] avatar dfrankland avatar dsernst avatar errorpro avatar frenzzy avatar futpib avatar koistya avatar langpavel avatar mastahdocent avatar moralcode avatar phpeek avatar sanches89 avatar sgpinkus avatar vidaaudrey avatar yosqueoy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

universal-router's Issues

Nested URL Generation - Cannot set property 'parent' of undefined

I'm getting the following error when I try to generate a url for a nested route.

router.root.children is getting logged as follows:

[ { path: '/:division', name: 'division', action: [Function: action], children: [ undefined ], parent: { path: '/', name: 'root', children: [Circular], action: [Function: action], parent: null } } ]

I'm not sure why children: is showing up as [ undefined ] as actual routing is working fine. My issue is specifically related to url generation.

Stack trace is as follows:

TypeError: Cannot set property 'parent' of undefined at update (/var/www/node_modules/src/generateUrls.js:27:9) at update (/var/www/node_modules/universal-router/generateUrls/main.js:30:9) at UrlService.url (/var/www/node_modules/universal-router/generateUrls/main.js:39:7) at UrlService.getUrl (/var/www/build/webpack:/service/UrlService.js:17:17) at Login.render (/var/www/build/webpack:/routes/client/auth/default/Login.js:46:57) at /var/www/node_modules/react/lib/ReactCompositeComponent.js:793:21 at measureLifeCyclePerf (/var/www/node_modules/react/lib/ReactCompositeComponent.js:74:12) at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (/var/www/node_modules/react/lib/ReactCompositeComponent.js:792:27) at ReactCompositeComponentWrapper._renderValidatedComponent (/var/www/node_modules/react/lib/ReactCompositeComponent.js:819:34) at ReactCompositeComponentWrapper.performInitialMount (/var/www/node_modules/react/lib/ReactCompositeComponent.js:361:30) at ReactCompositeComponentWrapper.mountComponent (/var/www/node_modules/react/lib/ReactCompositeComponent.js:257:21) at Object.mountComponent (/var/www/node_modules/react/lib/ReactReconciler.js:47:35) at ReactCompositeComponentWrapper.performInitialMount (/var/www/node_modules/react/lib/ReactCompositeComponent.js:370:34) at ReactCompositeComponentWrapper.mountComponent (/var/www/node_modules/react/lib/ReactCompositeComponent.js:257:21) at Object.mountComponent (/var/www/node_modules/react/lib/ReactReconciler.js:47:35) at /var/www/node_modules/react/lib/ReactServerRendering.js:46:36 at ReactServerRenderingTransaction.perform (/var/www/node_modules/react/lib/Transaction.js:138:20) at renderToStringImpl (/var/www/node_modules/react/lib/ReactServerRendering.js:44:24) at Object.renderToString (/var/www/node_modules/react/lib/ReactServerRendering.js:74:10) at _callee$ (/var/www/build/webpack:/server.js:179:30) at tryCatch (/var/www/node_modules/regenerator-runtime/runtime.js:63:40) at GeneratorFunctionPrototype.invoke [as _invoke] (/var/www/node_modules/regenerator-runtime/runtime.js:337:22) at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/var/www/node_modules/regenerator-runtime/runtime.js:96:21) at step (/var/www/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30) at /var/www/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13 at process._tickDomainCallback (internal/process/next_tick.js:129:7)

How to render children routes' components

If I have children routes, how do I use parent route's component as a container for all children routes to render in?

For example:


path: '/auth',
  component: <Auth title={title} />,

  children: [
    {
      path: '/login',
      action: () => {
        return {
          title,
          component: <Login title={title} />,
        };
      },
    },
    {
      path: '/register',
      action: () => {
        return {
          title,
          component: <Register title={title} />,
        };
      },
    },

And then in Auth component, I have {this.props.children} where children component should be rendered at. Is there a way to achieve this in Universal Router?

How to use context.params with Apollo client

I have a route (/client/:id) that points to a component Client. In Client I want to take the ID from context.params and use it as a parameter for my Apollo query.

Apollo has a HOC called graphql that has an "options" parameter. options can be a function that takes in the component props and allows you to transfer the props to the Apollo query. I don't see any way to access the context from within that options function.

Has anybody else run into this issue? Is there a way inside of react to automatically transfer the context to a parameter, or is there a way to do this with Universal Router?

Best practice for having multiple routes point to the same page?

What is best practice for having multiple routes point to the same canonical page? E.g.:

  • /autos/automatic/diesel (this is also the canonical URL)
  • /autos/diesel/automatic

Having both routes work is better UX for the user, and both pages will always display exactly the same information.

One option is something like the following, although it risks typos and missed updates if the page component props change. Even better would be specifying multiple paths in a single route object. Is there any way of doing this or another way of generating multiple routes that point to a single canonical URL?

const canonicalRelPath = '/autos/automatic/diesel';
const alternateRelPath = '/autos/diesel/automatic';

export default {
  path: canonicalRelPath,
  action() {
    return <AutomaticDieselLandingPage canonicalPath={url.resolve(base_url, canonicalRelPath)}/>;
  },
};

export const alternatePath = {
  path: alternateRelPath,
  action() {
    return <AutomaticDieselLandingPage canonicalPath={url.resolve(base_url, canonicalRelPath)}/>;
  },
};

How to configure to Rollup?

# Error Message:
node_modules\regenerator-runtime\runtime-module.js (5:303) 
The 'this' keyword is equivalent to 'undefined' at the top level of an ES module,
and has been rewritten.
// app.js
import { resolve } from 'universal-router';

const routes = [
  { path: '/', action: () => '<h1>Page One</h1>' },
  { path: '/two', action: () => '<h1>Page Two</h1>' },
  { path: '*', action: () => '<h1>Not Found</h1>' }
];

resolve(routes, { path: '/' }).then(result => {
  document.body.innerHTML = result;
});

resolve(routes, { path: '/two' }).then(result => {
  document.body.innerHTML = result;
});

resolve(routes, { path: '*' }).then(result => {
  document.body.innerHTML = result;
});

// Can I use `Promise.all`?
[...]
  return rollup({
      entry: path.join(SOURCE_ROOT, 'app.js'),
      format: 'iife',
      plugins: [
        globals(),
        builtins(),
        resolve({ jsnext: true, browser: true }),
        commonjs(),
        babel()
      ]
    })
[...]

Route priorities

Hi, in my project I along with route path like /welcome, /sign_in (specific string matched) I have also path /:id. I've found only way to match this route is to place it on top of routes
so it looks like:

const routes = [
  { path: '/:id', name: 'idRoute' },
  { path: '/welcome', name: 'welcome' },
  { path: '/sign_in', name: 'signIn' }
];

And it seems kind of strange for routes to be resolved bottom->top, wouldn't it make more sense to go top->bottom? So it checks all routes first and if none matches then it comes to /:id ?

How to create REST routes on SB Admin React Starter Kit

Hi koistya, I'm newbie in React JS, I'm using SB Admin React Starter Kit to create my app, I wish to create kind REST routes :

http://example.com/users
http://example.com/users/1
http://example.com/users/create
http://example.com/users/add

But I can't figure out how to make it, may you can help me to solve my problem ?


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/38907533-how-to-create-rest-routes-on-sb-admin-react-starter-kit?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).

I don't understand how "Universal Router" is working

Hello, guys!

Your router looks great on a slides and simple in docs. Actually, too simple.

It promos like 'isomorphic', but I can't find how to work with HTML5 History API and NodeJS http requests too. It seems this router can't capture nothing and I need to call function "resolve" manually each time the route is changed (on the server and on the client in different ways). So, could you explain which part of this router is "isomorphic" and why it's called "router", if it can't observe routing paths by itself?

Thanks!

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39745948-i-don-t-understand-how-universal-router-is-working?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).

Post queries?

Using the react-starterkit setup and have added a new route /authenticate. When I post to the route, I get a response "Cannot POST /authenticate". However, it will happily route to it via a GET.

for example:
on('/authenticate', async () => <div>hello</div>);
will error with a POST, but return the element with a GET. Does the router support POST operations or am I doing something very wrong?

How do you change routes...

without reloading the page? there are tricks like transitionTo and history in react-router; do these work with react-routing as well?

Dave

Tuning the app.js run method

Hi @koistya ! I've been playing with the kit these days and I've found one interesting detail that might bring to your attention.

It's all about the 'isomorphic' server side rendering.

When the user initially loads the app, the whole app is shipped through an HTML file which is being rendered lightning fast. However, when you press F12 and check the network flow then you will see that another API call for the identical URL is made for the currently loaded web page. Suddenly I noticed that app.js file does not know about the fact that the page has already been rendered by the server! Wouldn't it be sweet to add some property to app.js like 'serverRendered' and check it in run method? ;p

Usage with Redux

Hi all,

First of all, great work on this project. I like how universal-router isn't tightly coupled to the browser history/navigation code, making it a very versatile routing library.

Speaking of which, it seems that the recommended way to navigate and respond to location changes is to pair universal-router + history, as shown in #72 and in React Starter Kit.

This generally works well — however, it doesn't fit into the Redux architecture and thus breaks the devtools experience (time-travel debugging, etc).


I'd like to share an alternative, "Redux-first" method for achieving navigation and location listening. It allows:

  • the location data to be held in the store (and act as the source of truth for location data)
  • responding to location changes via subscribing to the store
  • navigating by dispatching actions (which handle updating the store and browser history together).

This is achievable with just a small amount of boilerplate code (Redux middleware, reducer, and action creators), which I've packaged into a library: redux-first-routing.

Here's what you get on the state tree:

{
  ..., // other redux state 
  router: {
    pathname: '/nested/path/',
    search: '?with=query',
    queries: {
      with: 'query',
    },
    hash: '#and-hash'
  }
}

Together, universal-router + redux-first-routing can be used to create a complete Redux routing solution for any front-end framework/library:

Usage with Universal Router

You can find a basic code recipe and live demo here:

And you can apply the same techniques to a larger application, like React Starter Kit's feature/redux branch.


Related: #43, #86


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

URL redirect && `dispatch` to return promise

I am trying to think of a way to do redirection.
Here are some examples, of which one requires dispatch to return promise.

// Redirect / to /home
{on("/", async() => {
     const {state, component} = await this.dispatch("/home");
     return component;
})}

Or provide a new api redirect (same level as on)?

redirct("/", "/home");

Apparently second one is better. Maybe adding this will be good?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/31733774-url-redirect-dispatch-to-return-promise?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).

redirect route? authorized routes

How would you do this ? to make sure that the url is authorized

**Update:

Answer from @koistya on Gitter:

One way to do so is to have a route handler similar to this one const authorize = (state, next) => { if (!state.user) { state.redirect = '/login'; next(); } } and then in your routes file:
on('/admin/users', authorize, (state) => )
And add a handler in your render function which checks if state.redirect was set, and if so redirect user to the new location by using Location.pushState(null, state.redirect) on a client, and req.redirect(state.redirect) on server

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/26405822-redirect-route-authorized-routes?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).

i18n paths

So I've been banging my head on this one.

Using react-intl, how can I go from

export default {

  path: '/myurl',

to

export default {

  path: formatMessage({ id: route.myurl }),

Thanks! #

Problem with history on Chrome for iOS?

I have used react-routing in my react app (via react-starter-kit). It works fine on all browsers except for Chrome on iOS. The root url keeps on reloading. I was looking for possible causes and stumbled across this thread on react-router. There was some issue with history api. I am guessing a similar issue for react-routing. I din't find a way to debug chrome on ios. Can anyone help?

Question: save url params in redux store and don't render previous connected route with the new params

// Let's say we have these 2 routes:

// `/home/:myValueA` route
async action(args) {
  args.context.store.dispatch({type: 'onRouteEnter', params: args.params});// or
  return (
    <Home />
  );
},

// `/other/:myValueB` route
async action(args) {
  args.context.store.dispatch({type: 'onRouteEnter', params: args.params});
  return (
    <Other />
  );
},

// Let's say we are in the `/home` route
// and we navigate to the `/other` route.
// The problem is that when it enters the `/other` route it dispatches the `onRouteEnter` action;
// The reducer will save the `params` in the store;
// Now the `<Home/>` component is connected to the store so it will render again and
// will get the new `params` value; <-- this is the problem, because sometimes is not what we want.
// After that the `<Other />` component is rendered and will use the new `params`;

// Question: How do you solve this issue? How do you make sure `<Home/>` component is not called with
// the `params` of the `/other` route?

One of the reason that I would prefer to keep it in the store is because you can use time travel with redux devtools. If you do like in your example, the url doesn't change when the you go back in the redux devtools timeline.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/38300428-question-save-url-params-in-redux-store-and-don-t-render-previous-connected-route-with-the-new-params?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).

support anchor?

does it support anchor?
just like click on tag: <a href="#position1">jump</a>,
the page scroll to the position of the tag: <a name="positon1">position1</a>


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Transitions

Provide a mechanism to do smooth animated transitions to a different route.
Consider also the same route with different parameters. Ex: /user/123 to/user/124.
Ideally it can work with ReactCSSTransitionGroup

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/29560423-transitions?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).

docs issue?

Hi Konstantin,

Could the docs for react-routing be outdated? The README file shows examples of router.use(...) and router.route(...), but those don't seem to work or exist in the source code.

Thanks!
Bruno

Named routes?

Any plans to add named routes? Hardcoding hrefs feels very permanent. Named routes allow you to completely separate URL structure logic from your views.

I understand that you're trying to keep this lightweight -- however I feel having named routes and a transition function that takes the parameters as args helps keep all URL related logic in the router.

Otherwise, URL changes mean switching out hrefs in the views.

Thoughts?

Full support of query params

Hi guys!
Thanks for the awesome work!

I want to suggest a feature: full support of query params. Query params should be first-class citizens of a router. For example, when I generate an url generateUrl(routeName, params), I want a router to generate a full url, including query params. All params that are not a part of a route itself should go to the query part.

For example:

  1. Route name: 'user'
  2. Route path: /user/:username
  3. generateUrl('user', {username: 'John', busy: 1}) should generate /user/John?busy=1

Of course, there should be a possibility to provide a function to generate query strings.

I know, you want to keep the router tiny and simple. So I'll not wonder if you decline this feature request. But:

  1. Such feature will bring simplicity for router users.
  2. There's no proper way to implement such feature outside of router (Well, there's a way with handling query params as separate object: generateUrl(routeName, params, queryParams), but I don't think that user of generateUrl function should think what params are belong to route and what should go to query string.)

Make params available to child routes

I have a route that has an :id parameter and also contains a bunch of children. The children of this route need access to the :id parameter but right now the only way to get it is to parse context.baseUrl.

There should be a way to access the params from the parent route in each of the children.

Back Functionality

Hi there. First off, your code is fantastic. I'm loving working with it.

Second, I'm trying to build a default handler for the browser back button. My thought was to have the router have a history array and push the states onto it (with a cap of course) and then if the user pushes the back button I could use the handlePopState event handler, pop the last state off and reapply it.

I have this all coded up but have a few questions:

  1. Were you already working on functionality for this?
  2. I can't figure out how to use npm link react-routing. When I do, even after doing npm run-script build it gives me this error:
/Users/jjung/dev/web/jd-demos/build/webpack:/src/router.js:4
import Router from 'react-routing/src/Router';
                   ^
Error: Cannot find module "react-routing/src/Router"
    at webpackMissingModule (/Users/jjung/dev/web/jd-demos/build/webpack:/src/router.js:4:20)
    at Object.module.exports.Object.defineProperty.value (/Users/jjung/dev/web/jd-    demos/build/webpack:/src/router.js:4:20)
    at __webpack_require__ (/Users/jjung/dev/web/jd-demos/build/webpack:/webpack/bootstrap     14ccd3919092f1554a9b:19:1)
    at Object.<anonymous> (/Users/jjung/dev/web/jd-demos/build/webpack:/src/server.js:9:40)
    at __webpack_require__ (/Users/jjung/dev/web/jd-demos/build/webpack:/webpack/bootstrap     14ccd3919092f1554a9b:19:1)
    at module.exports._this2 (/Users/jjung/dev/web/jd-demos/build/webpack:/webpack/bootstrap 14ccd3919092f1554a9b:39:1)
    at Object.<anonymous> (/Users/jjung/dev/web/jd-demos/build/webpack:/webpack/bootstrap 14ccd3919092f1554a9b:39:1)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)`

Rename match() to resolve()

What do you think about renaming match() method to resolve()? This method doesn't only find the route matching the given URL path, but also executes its action method and returns result to the caller.

API fetch calls

Hi,

When using Universal Router with React Starter Kit, any API requests using either fetch or Axios (for example in routes/home/index.js) will call the API endpoint twice.

Any idea why?

Update March 25:
The double call only happens when server-side rendering is called. Accessing the route client-side triggers a single API request.

Update layout for the documentation site

URL

http://www.kriasoft.com/react-routing

Source Code

/docs/index.html - site layout based on lodash.template
/docs/css/*.css - CSS4 styles based on PostCSS, cssnext
/docs/*.md - site pages (markdown with highlight.js support)

How to Run

npm start    # starts a lightweight development server, to run the documentation site locally

Compilation logic for it is located in /tools/serve.js

To-Do

  • Pass current URL and path of the original .md file to index.html (see tools/serve.js)
  • Add side menu for all the inner pages
  • Make large header appear only on the home page
  • Add Edit on GitHub button on all pages
  • Add footer
  • Add Disqus comments on inner pages

Need to republish after changing package.json

This is the currently lib/Match.js file that is pulled down during npm install,

/**
 * React Routing | http://www.kriasoft.com/react-routing
 * Copyright (c) Konstantin Tarkus <[email protected]> | The MIT License
 */

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Match = function Match(route, path, match) {
  _classCallCheck(this, Match);

  this.route = route;
  this.path = path;
  this.match = match;
};

exports["default"] = Match;
module.exports = exports["default"];

As of 0.0.4 it should be:

/**
 * React Routing | http://www.kriasoft.com/react-routing
 * Copyright (c) Konstantin Tarkus <[email protected]> | The MIT License
 */

'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

var Match = function Match(route, path, keys, match) {
  _classCallCheck(this, Match);

  this.route = route;
  this.path = path;
  this.params = Object.create(null);
  for (var i = 1; i < match.length; i++) {
    this.params[keys[i - 1].name] = decodeParam(match[i]);
  }
};

function decodeParam(val) {
  if (!(typeof val === 'string' || val instanceof String)) {
    return val;
  }

  try {
    return decodeURIComponent(val);
  } catch (e) {
    var err = new TypeError('Failed to decode param \'' + val + '\'');
    err.status = 400;
    throw err;
  }
}

exports['default'] = Match;
module.exports = exports['default'];

ie8 throw error

hi,when i use it ie8,thorw one error:

Unhandled promise rejection TypeError: Object does not support the "next" property or method.

async function next() {
if (({ value, done } = handlers.next()) && !done) {
const [match, handler] = value;
state.params = match.params;
return handler.length > 1 ?
await handler(state, next) : await handler(state);
}
}

child routes seem not to work

The following code in will never hit the /:cid subpath:

export default {
  path: '/clients',
  action: () => <Clients />,
  children: [
    {
      path: '/:cid',
      action(context) {
        console.log('action /:cid');
        return context.params.cid;
      }
    }
  ]
};

Example of breadcrumbs?

I'd like to have breadcrumbs for my site. Does anyone have recommendations for implementing them as part of universal-router? Thanks.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/36212127-example-of-breadcrumbs?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).

A version of Universal Router that does not depend on generators

Hi, I just wanted to let you guys know that I love Universal Router. I think it's a brilliant piece of code!

I ended up forking it though, because I didn't want to include babel-runtime and babel-regenerator-runtime in my web bundle. I released the fork as uroute. Maybe it can be of use to others that can't / don't want to depend on generator functions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.