# @olefjaerestad/router

> Lightweight client side JavaScript router to run certain code at certain URL routes.

Latest version **0.0.4** (published 2020-07-28) · MIT license · 0 weekly downloads

## Install

```sh
npm install @olefjaerestad/router
pnpm add @olefjaerestad/router
yarn add @olefjaerestad/router
bun add @olefjaerestad/router
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types; pre 1.0.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 0.0.4 |
| Published | 2020-07-28 |
| First published | 2020-06-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 60.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Ole Kristian Fjærestad |
| Maintainers | olefjaerestad |
| Keywords | router |

## Links

- npm: https://www.npmjs.com/package/@olefjaerestad/router
- Repository: https://github.com/olefjaerestad/router
- Homepage: https://github.com/olefjaerestad/router#readme
- Issues: https://github.com/olefjaerestad/router/issues
- npm.io page: https://npm.io/package/@olefjaerestad/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

- 0.0.4 (latest) — 2020-07-28
- 0.0.3 — 2020-07-28
- 0.0.2 — 2020-06-18
- 0.0.1 — 2020-06-18

## README

# Router
Lightweight client side JavaScript router to run certain code at certain URL routes.

## Installation
```bash
npm i @olefjaerestad/router
```

## API/examples
TODO:

### Create a router
```javascript
import { Router } from '@olefjaerestad/router';

const router = new Router();
```

### Run callback function at specific route
```javascript
/* Log req when route is '/home'. */
router.get('/home', (req) => console.log(req));

/* Do additional logging when route is '/home'. Will _not_ overwrite previously registered callbacks for the same route. */
router.get('/home', (req) => console.log('Another callback at /home'));

/* Within non-arrow callbacks, this = the Router instance. */
router.get('/about', function(req) {
	console.log(this); // Router
});
```

> Note: You can call `Router.get` on the same route as many times as you need.

### Fallback route
You might want some code to run when no routes are matched. You can do this by adding a '/404' route.

```javascript
/* This route will trigger when no routes are matched. */
router.get('/404', (req) => console.log(req));
```

> Note: This route will trigger both if no routes are matched or if the current route is '/404'.

### Route params
Routes don't have to be static. Just like in Express, you can use route parameters. For all possible syntaxes, see [Route parameters in Express](https://expressjs.com/tr/guide/routing.html#route-parameters).

```javascript
router.get('/blog/:slug/:id/:test', (req) => {
	console.log(req.params.slug);
	console.log(req.params.id);
	console.log(req.params.test);
});
```

Given the code above and a route of `/blog/my-post/123/hello`, the following will be logged:

```
my-post
123
hello
```

### Delete route
```javascript
/* Stop running callback functions for '/home' route. */
router.delete('/home');
```

### Middleware
In addition to a callback function, Router.get() also supports middleware. Much like [Express middleware](https://expressjs.com/en/guide/using-middleware.html), middleware are basically additional callback functions that can alter the `req` object or stop the execution of further route middleware and the route callback.

Alter the `req` object:
```javascript
const reqMiddleware = (req) => myFunc() ? req.foo = 'bar' ? null;

/* req.foo will be 'bar' or undefined, depending on the result of myFunc(). */
router.get('/home', reqMiddleware, (req) => console.log(req.foo));
```

Stop the execution of further route middleware and the route callback:
```javascript
const authMiddleware = (req) => isLoggedIn();

/* If authMiddleware() === false, req won't be logged even if route is '/home'. */
router.get('/home', authMiddleware, (req) => console.log(req));
```

> Note: Middleware will be ran in the order they are passed to `Router.get()`, from left to right.

> Note 2: Returning false in a middleware will only affect the callback/middleware that were registered in the same `Router.get()` call as it. Modifying `req` however, will affect callbacks/middleware across all `Router.get()` calls for that route.

### Async middleware and callbacks
Middleware and callbacks can also be async, which could be useful when doing things like network requests, authentication, etc.

```javascript
const authMiddleware = async (req) => await isLoggedIn();

/* If authMiddleware() === false, callback won't run even if route is '/home'. */
router.get('/home', authMiddleware, async (req) => {
	const result = await getPromise();
	console.log(result);
});
```

> Note: Async middleware must resolve (be completed) before the next middleware/callback starts executing.

### The request object
You might've already seen the `req` object being passed to middleware and callbacks. This is an object containing information about your current route. The object has the the following properties:
- `req.route` - A string containing the current route.
- `req.params` - An object with key-value pairs containing the route parameters. Note that number params (e.g. IDs) are converted to numbers. All others params are strings.

### Navigating to route
```javascript
router.navigate('/home');
```

Router instances also add event listeners to the window and document, so that `[router-href]` elements and browser back/forwards buttons can be used to trigger routes. Router.removeEventListeners() can be used to cleanup (i.e. remove) these event listeners.

```html
<!-- Click to navigate to the '/about' route. -->
<a href="" router-href="/about" title="See info about me">About</a>
```

> Note: If `router-href` is empty, the element will be treated as a normal link.

> Note 2: `router-href` can be used on any element, not just links. Be aware of accessibility concerns if doing this.

## Typescript
The package supports typings through .d.ts files. The following named exports are exported from the package:
- Router: class that creates a router.
- IRouterCallback: interface for the router middleware and callbacks.

## Browser support
TODO: Update table below.

| Browser                  | Supported? |
| :--                      | :--        |
| Chrome >= 55             | ✅         |
| Firefox >= 52            | ✅         |
| Safari >= 10.1           | ✅         |
| Opera >= 42              | ✅         |
| Edge >= 15               | ✅         |
| Internet Explorer        | ❌         |
| Chrome for Android > 55  | ✅         |
| Firefox for Android > 52 | ✅         |
| Opera for Android > 42   | ✅         |
| Safari for iOS > 10.3    | ✅         |
| Node.js                  | ❌         |

Browser support is mainly affected by use of the following:
- [Classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)
- [async await syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)

## Developing
```bash
npm run dev
```

Then just start editing the code in `/src`. If using an editor with good TypeScript support (e.g. VS Code), any errors will be inlined in the code as well.

> Note: Dev produces no output files.

## Testing
Integration testing:

```bash
npm run test:browsers
```

This will open a separate window where you can choose which browser to test in. Note that browsers are limited to browsers that are installed on your system _and_ [supported by Cypress](https://docs.cypress.io/guides/guides/launching-browsers.html#Browsers).

## Building
```bash
npm run build
```

> Note: Build will fail and report if there are errors.

## Publishing
Publish to npm:

```bash
npm run publish:npm
```

> Note: Requires being [logged in to npm locally](https://docs.npmjs.com/cli/adduser).

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