A simple router for React applications
import { useUrl, route } from "bloody-use-url";
import { match } from "ts-pattern";
const App = () => {
const url = useUrl();
return match(url.path)
.with(route("/"), () => <h1>{`Home`}</h1>)
.with(route("/users"), () => <h1>{`Users`}</h1>)
.with(route("/users/:userId/*"), ({ userId, rest }) => (
<>
<h1>{`User ${userId}`}</h1>
<UserDetails path={rest} />
</>
))
.otherwise(() => <h1>Not found</h1>);
};
$ yarn add bloody-use-url ts-pattern
Hook to get the current URL:
const url = useUrl();
The returned value has the following type:
type Url = {
path: string[];
search: URLSearchParams;
hash: string;
pathname: string;
};
Pushes the page URL
push("/users/bloodyowl");
Replaces the page URL
replace("/users/bloodyowl");
Returns the current URL
const url = getUrl();
Returns the current URL
const unwatchUrl = watchUrl((url) => {
console.log(url);
});
// ...
unwatchUrl();
Blocks page navigation if shouldBlock
is true
.
useNavigationBlocker(
formStatus === "editing",
"Are you sure you want to leave this page?"
);
Returns whether the provided path is active
const isActive = useIsActivePath("/foo/bar");
Generates a pattern to be consumed by ts-pattern:
- Route params like
:paramName
are selected. - Rest params like
*
are selected asrest
.
return (
match(url.path)
.with(route("/"), () => <h1>{`Home`}</h1>)
.with(route("/users"), () => <h1>{`Users`}</h1>)
// `userId` & `rest` are correctly typed
.with(route("/users/:userId/*"), ({ userId, rest }) => (
<>
<h1>{`User ${userId}`}</h1>
<UserDetails path={rest} />
</>
))
.otherwise(() => <h1>Not found</h1>);
);
- Rescript React Router for the whole API
- Chicane for the TypeScript wizardy logic