# cs-router

> A lightweight router that works on server and client, hence the name cs-router, sharing routes, callbacks and code

Latest version **1.1.2** (published 2017-03-17) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install cs-router
pnpm add cs-router
yarn add cs-router
bun add cs-router
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 1.1.2 |
| Published | 2017-03-17 |
| First published | 2017-02-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Roy Niels |
| Maintainers | braadworst |
| Keywords | Router, Client, Server, Lightweight, Shared, routes, shared, callbacks |

## Links

- npm: https://www.npmjs.com/package/cs-router
- Repository: https://github.com/braadworst/cs-router
- Homepage: https://github.com/braadworst/cs-router#readme
- Issues: https://github.com/braadworst/cs-router/issues
- npm.io page: https://npm.io/package/cs-router

## Alternatives

- [express-promise-router](https://npm.io/package/express-promise-router.md) — 736.1K weekly downloads
- [next-usequerystate](https://npm.io/package/next-usequerystate.md) — 29.8K weekly downloads
- [@bitkyc08/opencodex](https://npm.io/package/@bitkyc08/opencodex.md) — 4.6K weekly downloads
- [lynkr](https://npm.io/package/lynkr.md) — 575 weekly downloads
- [baremetal.js](https://npm.io/package/baremetal.js.md) — 42 weekly downloads

## Recent versions

- 1.1.2 (latest) — 2017-03-17
- 1.1.1 — 2017-03-17
- 1.1.0 — 2017-03-03
- 1.0.6 — 2017-03-01
- 1.0.5 — 2017-03-01
- 1.0.4 — 2017-02-20
- 1.0.3 — 2017-02-20
- 1.0.2 — 2017-02-20
- 1.0.1 — 2017-02-20
- 1.0.0 — 2017-02-20

## README

# Lightweight Client/Server router (no dependencies)

A router that works on the client and server (isomorphic) and is lightweight as f*. Routes, callbacks are shared between client and server. Package has no dependencies(!). Pure ES6 JS. You will still be able to add client/server specific calls.

## Why another router?
I have been using expressjs and pagejs for a while but I wasn't satisfied. Although they look very similar (similar function footprint) having my routes defined in a single place turned out to be a tricky business. I tried it with currying my functions (separate the paths, which are the thing you actually wanna unify) and came close. The nature of express is unfortunately that it internally uses the `this` keyword. My curried functions would make it lose context and you had to start using `.call` or `.apply` ,blegh, ugly...

Besides that I only needed a router and not a full fletched express kinda tool. Performance gain (express isn't the quickist kid on the block you know) and ease of unifying my routes made me write this package.

## Version 1.1.0 update
- Added some tests, because hey, who will take you seriously if you don't...
- Added clientside redirect (see redirect for examples)
- Added fallback for routes that don't match a pattern
- Added most HTTP methods
- Added some console.warnings so you don't look for an hour when a pattern match couldn't be made
- Updated the docs

_NOTE: the response object is only available on the server, you need to call it explicitly when doing some routes, otherwise your server hangs. But if you are building a single page app (SPA) you wanna send the index.html anyway._

Missing something, bugs, you know Github right...

### Considering the following dir structure
```
.
+- client
|  +- main.js
+- server
|  +- main.js
+- shared
   +- router.js
```

I browserify the client and shared folder (put as much as I can in the shared folder).

#### client/main.js
```
document.addEventListener("DOMContentLoaded", event => {
  const router = require('../shared/router')();
});
```

#### server/main.js
```
// Run any http module (spdy, https, etc)
const http = require('http');

const server = http.createServer();

const router = require('../shared/router')(server);

// Define some server only calls
router.get('/somepath', (request, response) => {
  // do something
});

http.listen(8080);
```

#### shared/router.js
```
module.exports = function(server) {
  const router = require('cs-router')(server);

  router.get('/someroute/:id', (request, response) => {
    // Do stuff, for example some redux action generator calls
  });
  router.post('/otherroute', (request, response) => {
    // handle..
  });
  router.delete('/otherroute', (request, response) => {
    // handle..
  });
  router.update('/otherroute', (request, response) => {
    // handle..
  });
  router.put('/otherroute', (request, response) => {
    // handle..
  });
  router.options('/otherroute', (request, response) => {
    // handle..
  });
  router.noMatch('/otherroute', (request, response) => {
    // handle..
  });
  // Called on all routes before the specific path call
  router.before((request, response) => {
    // handle
  });
  // Called on all routes after the specific path call
  router.after((request, response) => {
    // handle
  })
}
```

### Parameters
```
router.get('/somepath/:id', (request, response) => {
  console.log(request.params.id) // 1;
});
http.get('/somepath/1');
```

### Redirects
The router has a coded way of redirecting urls, this build in functionality works
only on the clientside, but for completeness I will give an example how you can achieve
some redirects on the serverside (for example after an OAuth call to a third party)

#### Clientside
```
router.redirect('/newpath'); // Pretty simple stuff
```
#### serverside
```
router.get('/newpath', (request, response) => {
  // Some stuff
});
router.get('/somepath', (request, response) => {
  response.end();
  http.request({ // Standard node stuff, or use a lib like request...
    path : '/newpath',
    host : 'localhost',
    port : '4443',
    method : 'get'
  });
});
```

### Carrying variables over to other hooks
Sometimes it might be handy to carry over some variables from one hook to another,
for example when you wanna create a new redux store on each serverside request.
```
router.before((request, response) => {
  // create a store somehow
  store = createStore();

  // The return value needs to be an object
  return {
    store
  }
});

router.get('/somepath', (request, response, args) => {
  console.log(args.store) // Store is available
});
```
Arguments carried over like this will be destroyed after a full request update cycle,
that is after the last _after_ statement has run (if hooked into)

### Fallback for non matching routes
Sometimes you might have a request that cannot be matched. Assigning the noMatch callback
will let you work with these
```
router.noMatch((request, response) => {
  // Handle requests that could not be matched
});
```

### Tests
```
npm run test // in the package obviously
```

---
_Source: https://npm.io/package/cs-router · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
