Primitives for building your own router.
match()
provides flexible rule-based URL matching.
You can:
- Use a path-only rule:
match({ path: "/account/:accountId" }, "/account/123");
result = {
params: {
accountId: "123";
}
}
- 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"
}
};
- 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"
}
};
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);