/core-router

Primitives for building your own router

Primary LanguageTypeScriptMIT LicenseMIT

core-router

Primitives for building your own router.

Matching URLs with match()

match() provides flexible rule-based URL matching.

You can:

  1. Use a path-only rule:
match({ path: "/account/:accountId" }, "/account/123");

result = {
  params: {
    accountId: "123";
  }
}
  1. Combine path, search params, and a condition:
match(
  {
    path: "/account/:accountId",
    search: {
      from: ":fromDate?",
      to: ":toDate?"
    },
    condition: ({ params }) => {
      return isDate(params.fromDate) && isDate(params.toDate);
    }
  },
  "/account/123?from=2020-01-01&to=2020-01-31"
);

result = {
  params: {
    accountId: "123",
    fromDate: "2020-01-01",
    toDate: "2020-01-31"
  }
};
  1. Or fallback to completely custom logic:
match(
  {
    condition: ({ url }) => {
      return url.hash === "#secret";
    }
  },
  "/you/must/have/the#secret"
);

result = {
  params: {}
};

Absolute URLs will only match if they belong to the same domain:

// On https://foo.com:
match({ path: "/hello" }, "https://bar.com/hello");

result = null;

Params will be decoded for you:

match({ search: { q: ":searchTerms" } }, "/?q=hello%20world");

result = {
  params: {
    searchTerms: "hello world"
  }
};

Generating URLs with toHref()

Any rule that can be used for match() can also be used to generate a relative URL.

toHref({ path: "/account/:accountId" }, { accountId: "123" });

result = "/account/123";

If required params are not supplied, an error will be thrown:

toHref({ path: "/account/:accountId" }, {});
// Error!

Similarly, if the condition is not met, an error will alos be thrown:

toHref(
  {
    condition: ({ url }) => url.hash === "#secret"
  },
  "/#incorrect"
);
// Error!

This ensures that for any rule, a URL generated by toHref() will also match():

const href = toHref(myRule, myParams);
const matchResult = match(myRule, href);
expect(matchResult).not.toBe(null);
expect(matchResult.params).toEqual(myParams);