4.1.3 • Published 2 years ago

web-router.js v4.1.3

Weekly downloads
1
License
MIT
Repository
github
Last release
2 years ago

WebRouter.js

A modern vanilla JavaScript web router, inspired by Navigo API. Testing with Jest & JSDOM and bundled with microbundle.

Some of the improvements from the inspirational project: before, after and leave hook accept either a function or an array of functions. Previous methods can cancel the call chain for later methods see hooks section for details.

Additionally, improved RegExp matching, direct access to all routes, statically via WebRouter.routes, modern JavaScript codebase without the need for Babel and more.

Does not support hash routing. Consider Navigo if you need to support old browsers.

Usage

.on() Route Handlers

This method be called multiple times, see chaining section below. It accepts a route name, parameterized URL string or RegExp to match against. The second argument is the main render method and an optional third argument of hooks. See the hooks section for more information

const router = new WebRouter();
router.on('/somepage/:myParam', ({myParam})=>{
  console.log('Page loaded', myParam);
}).resolve();

.on() RegExp Handlers or Parameterized URL Strings

const router = new WebRouter();
router.on(/myapp\/(bar|car)\/([A-Za-z0-9]{10,})/, (arg1, arg2)=>{
  console.log('Page loaded', arg1, arg2);
})
router.on(/myapp\/search\/([^/]{1,})/, (searchPhrase)=>{
  // Render app
}, {
  before:(done, params)=>{
    // must call done. pass `false` to terminate
    done();
  }
});
router.on('/profile/:userName', ({userName})=>{
  // only called when URL is /profile/WebRouter
  // based on before
}, {
  before:(done, {userName})=>{
    if(userName === 'WebRouter') {
      done();
    } else {
      done(false);
    }
    
  }
});
router.resolve();

Accessing GET Parameters

Can be done easily with window.location.search, it is advisable to use the const params = new URLSearchParams(window.location.search) and params.get('getParamName')

.off() Route Handlers

Omitting all arguments will delete all routes from the router. To remove individual routes, pass in the matching path that was passed as the first argument to .on()

const route = new WebRouter();
route.on('/somepage/:myParam', ()=>{
  // ... rendering
});
// disable that route
route.off('/somepage/:myParam');

.navigate( url, [data] ) Method

You can initiate a navigation from JavaScript by using the router.navigate method. The navigate method can accept an optional second parameter, which will be passed to pushState and available via event.state.

.resolve( path ) Method

WebRouter isn't started until router.resolve() is called. As a default argument, when no arguments are passed, .resolve uses window.location.pathname. However, you can manually intercede by passing the URL of the route you would prefer to resolve.

.updatePageLinks() Method

Identical to navigo, WebRouter supports integration with existing links using the router.updatePageLinks() method call. Add the attribute data-navigo or data-route to enable a link integration with the WebRouter. WebRouter will use the href attribute and call navigate on the users behalf when they click the link.

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <div>
    <a href="/some/url" data-route>Regular Link</a>
  </div>
</body>
</html>
new WebRouter({
'/some/url':()=>{ /* ... */ } 
}).resolve();

WebRouter.reset() Method

Similar to passing no arguments to an instance .off() method, calling WebRouter.reset() will reset the application and all stored routes.

Hooks

Hooks allow access to routes before, after and when the user navigates away via leave. They can accept a single function, as declared below or an array of functions

With hooks, passing an explicit false or falsy value as the first argument will terminate the call chain. Like before, the after and leave hooks receive done callback. Additionally, passing an explicit false to the after and leave hooks will cause the hooks to terminate, but have no effect on the primary route method.

route.on('/', ()=>{}, {
  before:(done, params)=>{
    // before anything, call done();
  },
  after:(done, params)=>{
    // immediately after render
  },
  leave:(done, params)=>{
    // on user navigate away
  }
});

Hooks, array of functions

route.on('/', ()=>{}, {
  before:[(done, params)=>{
    // allow
    done();
  }, (done, params)=>{
    // can reject
    done(false)
  }],
  after:[(done, params)=>{
    done(false);
  }, (done, params)=>{
    // terminated by done(false) in first method
    done();
  }],
  leave:[(done, params)=>{
    // can terminate chain by done(false) 
    done();
  }]
});

Hooks can be used together or as needed. For instance, if you wanted to call 5 methods before a route is invoked, but do not need to use after or leave, that's possible. For instanc presume we want to see if a user has a token, get the credentials is a user has said token that's simple

router.on('/user', ()=>{
  const div = document.createElement('div')
  div.innerText = localStorage.getItem('user')
  document.body.appendChild(div);
}, {
  before:[(done, params)=>{
    const token = localStorage.getItem('token');
    if(!token) done(false);
    done();
  }, (done, params)=>{
    /**
      Assumes API response is
      {user:'your name'}
    */
    fetch('/v3/user')
      .then(data=>data.json())
      .then(data=>{
        localStorage.setItem('user', user.name);
        done();
      }).catch(err=>{
        done(false);
      })
  }];
})
Hook Detail: after called unless route changes

Please note, while this will not apply to most users, it's worth nothing that the after hooks will be called for a route unless the route explicitly changes even if you cancel in the before method.

Chaining .on(), .on() and .resolve()

WebRouter supports call chaining for easier declarative routes

const router = new WebRouter();
router.on(/^\/foo1\/([^/]{1,})$/, (arg1)=>{
  // Do main rendering...
}, {
  before:[(done,params)=>{
    // ...
    done();
  },(done, params)=>{
    // ...
    done();
  }]
}).on('/foo2', ()=>{
  // Do main rendering...
}, {
  after:[(done,params)=>{
    // ...
    done();
  },(done, params)=>{
    // ...
    done();
  }]
}).resolve();

Convenience, Simple Declarations

If you don't need any RegExp support in your route or hooks, you can use the first argument of the WebRouter constructor to declare routes.

const router = new WebRouter({
  '/foo1':()=>{
    /* ... */
  },
  '/foo2/field2':()=>{
    /* ... */
  }
});
Developing for WebRouter Project

Configuration For Testing: It is advised to use at least node version 16.6.2

nvm install 16.6.2
4.1.3

2 years ago

4.1.2

3 years ago

4.1.1

3 years ago

3.1.2

4 years ago

3.1.1

4 years ago

3.0.4

4 years ago

3.0.3

4 years ago

3.0.2

4 years ago

3.0.1

4 years ago

2.2.1

4 years ago

2.1.2

4 years ago

2.1.1

4 years ago

2.0.9

4 years ago

2.0.8

4 years ago

2.0.7

4 years ago

2.0.6

4 years ago

2.0.5

4 years ago