TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

Relay Router Core For Single Page Applications


  • Framework-agnostic
  • Path-To-Regex conversion
  • Middleware Support
  • Nested Routing


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!");

// Willcard route
// Matches everything else, routes that are registered after this will not be reached.
router.route("*", () => {
  console.log("No page found!");

// Unreachable route because it was registered after the wildcard route.
router.route("/unreachable", () => {
  // ...
  console.log("We are unreachable!");

// Start the router

// Programmatically navigate to a route

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!");

petsRouter.route("/pikachu", (_ctx, nav) => {
  // ...
  console.log("Pika pikaaaaa!");

// 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 :)");

// Register the nested router as a middleware to the main router
router.route("/pets", petsRouter);


// Now we can navigate to "/pets/george",
// which will print "Hello, I'm George the Dog! Woof!"

// Or to "/pets/pikachu", which will print "Pika pikaaaaa!"

// Or to jets "/pets", which will print "Root route, home of all pets :)"

// just "/pikachu" or "/george" or "/" will not work

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}`);


// 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

// Will not get called because the the previous handler already called nav.ok()
router.route("/user/:userId", () => {
  // unreachable


// Will cause the first two middlewares to be called


npm i @relayjs/core

DownloadsWeekly Downloads






Unpacked Size

137 kB

Total Files


Last publish


  • rencedm112