@relayjs/core
v1.0.1
Published
A Simple Framework-Agnostic Routing Library
Downloads
2
Maintainers
Readme
Relay Router Core For Single Page Applications
Features
- Framework-agnostic
- Path-To-Regex conversion
- Middleware Support
- Nested Routing
Docs
Click Here For Full Documentations
Basic Usage
import { Router, BrowserHistory } from "@relayjs/core";
const router = new Router(new BrowserHistory());
// Routes are matched in the order they are defined
// Routes should always be defined with a leading slash
// Matches paths that starts with "/home"
router.route("/home", (_ctx, nav) => {
// _ctx is a RouteContext object that contains the path, params, and query
// and other information about the current route
// nav is a NavigationContext object that has methods for
// signaling the router how to proceed with the navigation
console.log("We are at home!");
nav.ok(); // signals that the route was handled successfully
// not calling nav.ok() will make the router find the next matching route
// if no matching route is found, the router will throw an error
});
// Matches paths that starts with "/contact"
router.route("/contact", () => {
console.log("We are at contact!");
nav.ok();
});
// Willcard route
// Matches everything else, routes that are registered after this will not be reached.
router.route("*", () => {
console.log("No page found!");
nav.ok();
});
// Unreachable route because it was registered after the wildcard route.
router.route("/unreachable", () => {
// ...
console.log("We are unreachable!");
});
// Start the router
router.start();
// Programmatically navigate to a route
router.navigateTo("/contact");
Navigation using HTML Anchor Elements
<!--
Click on an anchor element with an attribute of either data-relay-link or relay-link
and it will trigger a navigation to the route that matches the href attribute.
-->
<a href="/home" data-relay-link>Home</a>
<a href="/contact" relay-link>Contact</a>
<!--
NOTE: Most of the time, paths should be absolute,
you can use relative paths but will be resolved relative to the current
location shown in the browser's address bar.
Example: if the current location is: https://example.com/page/home
-->
<a href="path">Will be resolved to https://example.com/page/path</a>
<a href="./path">Will be resolved to https://example.com/page/path</a>
<a href="../path">Will be resolved to https://example.com/path</a>
Nested Routing
import { Router, BrowserHistory } from "@relayjs/core";
const router = new Router(new BrowserHistory());
const petsRouter = Router.createNested();
petsRouter.route("/george", () => {
// ...
console.log("Hello, I'm George the Dog! Woof!");
nav.ok();
});
petsRouter.route("/pikachu", (_ctx, nav) => {
// ...
console.log("Pika pikaaaaa!");
nav.ok();
});
// Root routes, just like wildcard routes, match everything so
// they should be registered after all other routes.
petsRouter.route("/", (_ctx, nav) => {
// ...
console.log("Root route, home of all pets :)");
nav.ok();
});
// Register the nested router as a middleware to the main router
router.route("/pets", petsRouter);
router.start();
// Now we can navigate to "/pets/george",
// which will print "Hello, I'm George the Dog! Woof!"
router.navigateTo("/pets/george");
// Or to "/pets/pikachu", which will print "Pika pikaaaaa!"
router.navigateTo("/pets/pikachu");
// Or to jets "/pets", which will print "Root route, home of all pets :)"
router.navigateTo("/pets");
// just "/pikachu" or "/george" or "/" will not work
router.navigateTo("/pikachu");
router.navigateTo("/george");
router.navigateTo("/");
Path Parameters
import { Router, BrowserHistory } from "@relayjs/core";
const router = new Router(new BrowserHistory());
// We can define routes with path parameters
router.route("/user/:userId", (ctx, nav) => {
// Path parameters are defined with a colon prefix
// In this case, the path parameter is "userId"
// We can pass values to this route via the ":userId" path parameter
// To access the path parameter, the callback should
// should accept a context argument as the first paramter
// To access the path parameter value, we can use the context.param object
const userId = ctx.param.getString("userId");
console.log(`User ID: ${userId}`);
nav.ok();
});
router.start();
// We pass the parameter value in place of the ":userId" path parameter
router.navigateTo("/user/123"); // Will print "User ID: 123"
Middleware Support
import { Router, BrowserHistory } from "@relayjs/core";
const router = new Router(new BrowserHistory());
// Sometimes we want to inspect the context before we navigate to a route
// We can define middleware to do this
// Handlers and middlewares are the same thing from the perspective of the Router
// The only difference is that middlewares
// middlewares should not call nav.ok() so other handlers can be called
router.route("/user/:userId", (ctx) => {
// We can intercept the navigation
// do some actions first
const userId = context.param.getString("userId");
const userInfo = userApi.fetchInfo(userId);
// modify the context to pass some information to the next callback
// context.state can be used for this.
context.state = { userInfo }; // state is null by default
// NOTE: Only serializable objects should be passed to context.state
// such as primitives, arrays, and/or objects that contain serializable values
// We don't call nav.ok() here yet so the next handler will be called
});
// NOTE: The same route can have multiple middlewares
// They are called in the order they are registered
router.route("/user/:userId", (ctx, nav) => {
// We can access the information that was given by the middleware
const userInfo = context.state.userInfo;
console.log(`Name: ${userInfo.fullname}`);
// Finish the navigation here
nav.ok();
});
// Will not get called because the the previous handler already called nav.ok()
router.route("/user/:userId", () => {
// unreachable
});
router.start();
// Will cause the first two middlewares to be called
router.navigateTo("/user/123");