A simple router for preact with support for hash and browser routing.
browserandhashrouting types.- Support for lazy-loaded routes (
lazyloading). - Error handling.
- Fully typed.
- Ultra lightweight.
- Minimal external dependencies.
- Super fast route matching using unjs/rou3
npm install preact-hashish-router@latestFirst, ensure your application is wrapped within the router context. This will allow you to access routes and related functions.
import { NotFound, Route, Router, RouterErrorBoundary } from "preact-hashish-router";
import { About } from "./routes/About";
import { AllLevelWildcard } from "./routes/AllLevelWildcard";
import { Home } from "./routes/Home";
import { OneLevelWildcard } from "./routes/OneLevelWildcard";
import { ProductDetails } from "./routes/ProductDetails";
export function App() {
return (
<RouterErrorBoundary>
<Router type="browser">
<Route
path="/"
element={<Home />}
/>
<Route
path="/about"
element={<About />}
/>
<Route
path="/product/:id"
element={<ProductDetails />}
/>
<Route
path="/one-level-wildcard/*"
element={<OneLevelWildcard />}
/>
<Route
path="/all-level-wildcard/**"
element={<AllLevelWildcard />}
/>
<NotFound element={<h1>Custom Not Found Element</h1>} />
</Router>
</RouterErrorBoundary>
);
}The useRouter hook gives you access to the router context to programmatically navigate or retrieve information about the current route.
import { useRouter } from "preact-hashish-router";
function HomePage() {
const { go, params, path, searchParams } = useRouter();
function goToAbout() {
go("/about");
}
return (
<div>
<h1>Home Page</h1>
<button onClick={goToAbout}>Go to About</button>
</div>
);
}import { A } from "preact-hashish-router";
export default function Header() {
return (
<header>
<nav>
<A href="/">Home</A>
<A href="/about">About</A>
</nav>
</header>
);
}Alternative you can use createDataRouter
import { createDataRouter, NotFound, RouterErrorBoundary } from "preact-hashish-router";
import { lazy } from "preact/compat";
import { AllLevelWildcard } from "./routes/AllLevelWildcard";
import { Home } from "./routes/Home";
import { OneLevelWildcard } from "./routes/OneLevelWildcard";
import { ProductDetails } from "./routes/ProductDetails";
const AboutLazy = lazy(() => import("./routes/About"));
const DataRouter = createDataRouter([
{
path: "/",
element: <Home />,
children: [
{
path: "about",
lazy: true,
fallback: <h1>Loading About...</h1>,
element: <AboutLazy />,
children: [
{
path: "test",
element: <h1>About/test</h1>,
},
],
},
{
path: "product/:id",
element: <ProductDetails />,
},
{
path: "one-level-wildcard/*",
element: <OneLevelWildcard />,
},
{
path: "all-level-wildcard/**",
element: <AllLevelWildcard />,
},
],
},
]);
export function App() {
return (
<RouterErrorBoundary>
<DataRouter
onRouteDidChange={(url) => {
console.log("onRouteDidChange", url);
}}
onBeforeRouteChange={(url) => {
console.log("onBeforeRouteChange", url);
}}
>
<NotFound element={<h1>Custom Not Found Element</h1>} />
</DataRouter>
</RouterErrorBoundary>
);
}If you have any improvements or find any issues, feel free to contribute or open an issue in the associated repository.