The official React integration for route-weaver
. It provides a set of custom Hooks for seamless integration with your React applications, making it easy to access navigation data and functions with full typesafety.
Tired of string-based routing leading to runtime errors, broken links, and a frustrating developer experience? Traditional React routing libraries often leave you vulnerable to typos in route paths and mismatches in parameters, issues that typically only surface in the browser.
@route-weaver/react
solves this by bringing end-to-end typesafety to your routing. By defining your routes as a structured, typed object, you unlock a new level of confidence and productivity. This library doesn't just manage routes; it creates a contract between your route definitions and your components, ensuring that any attempt to navigate to a non-existent route or pass incorrect parameters is caught by TypeScript at build time, not by your users at runtime.
npm install @route-weaver/core @route-weaver/react
Start by defining your routes and creating a navigation instance with the "all-in-one" createNavigation
function. Then, create a fully typesafe React API using createRouteWeaverReactApi
.
This factory function returns the RouteWeaverProvider
and all the necessary hooks, with TypeScript types automatically inferred from your navInstance
.
// src/routing.ts
import { createNavigation } from '@route-weaver/core';
import { createRouteWeaverReactApi } from '@route-weaver/react';
const navInstance = createNavigation({
home: { path: '/', label: 'Home' },
about: { path: 'about', label: 'About' },
posts: { path: 'posts/:id', label: 'Posts' },
});
// Create the typesafe React API
export const {
RouteWeaverProvider,
useNavigation,
useActiveRoute,
useBreadcrumbs,
useBuildPath,
} = createRouteWeaverReactApi(navInstance);
Now, wrap your application with the RouteWeaverProvider
.
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import { RouteWeaverProvider } from './routing';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<Router>
<RouteWeaverProvider>
<App />
</RouteWeaverProvider>
</Router>
</React.StrictMode>
);
Note: For more advanced use cases, such as generating multiple navigation structures from a single set of routes, see the
@route-weaver/core
documentation. BothcreateNavigation
andcreateRouteWeaver
produce a fully typesafeNavigationInstance
.
- Why and When to Use: Use this hook to get the entire navigation object you defined. It's perfect for rendering navigation menus, lists of links, or any UI element that corresponds to a predefined set of routes.
-
Returns: The full
navigation
object, with each key corresponding to a navigation group.
Practical Example:
import { useNavigation } from './routing';
import { Link } from 'react-router-dom';
function Header() {
const navigation = useNavigation();
return (
<nav>
{navigation.main.map(item => (
<Link key={item.id} to={item.path}>
{item.label}
</Link>
))}
</nav>
);
}
- Why and When to Use: Use this hook to get the currently active route based on the URL. This is essential for highlighting the active link in a navigation menu, displaying the title of the current page, or fetching data specific to the current route.
-
Returns: An
ActiveRoute
object ({ route, params }
) orundefined
.
Practical Example:
import { useActiveRoute } from './routing';
function PageTitle() {
const activeRoute = useActiveRoute();
if (!activeRoute) {
return <h1>404 - Page Not Found</h1>;
}
return <h1>{activeRoute.route.label}</h1>;
}
- Why and When to Use: Use this hook to generate a breadcrumb trail for the current page. It helps users understand their location within your application's hierarchy and provides easy navigation back to parent pages.
-
Returns: An array of
StructuredNavItem
objects representing the path to the active route.
Practical Example:
import { useBreadcrumbs } from './routing';
import { Link } from 'react-router-dom';
function Breadcrumbs() {
const crumbs = useBreadcrumbs();
return (
<nav>
{crumbs.map((crumb, index) => (
<span key={crumb.id}>
<Link to={crumb.fullPath}>{crumb.label}</Link>
{index < crumbs.length - 1 && ' > '}
</span>
))}
</nav>
);
}
-
Why and When to Use: This is the cornerstone of typesafe navigation. Use this hook to get the
buildPath
function, which allows you to construct URLs in a completely typesafe way. It eliminates the risk of typos in paths or parameters, as TypeScript will validate everything at compile time. -
Returns: The
buildPath(routeId, params)
function from the corerouteWeaver
instance.
Practical Example:
import { useBuildPath } from './routing';
import { Link } from 'react-router-dom';
function UserProfileLink({ userId }: { userId: string }) {
const buildPath = useBuildPath();
// Typesafe: 'posts' is a valid route and 'id' is a required param.
const profilePath = buildPath('posts', { id: userId });
return <Link to={profilePath}>View Profile</Link>;
}
Without route-weaver
, you might build links with string interpolation, a common source of bugs.
// If the route changes from '/users/:id' to '/profile/:id', this link will break silently.
const profilePath = `/users/${userId}`;
This is fragile. There's no guarantee /users/:id
is a valid route, and refactoring is a nightmare.
With route-weaver
, useBuildPath
gives you full typesafety and autocompletion.
import { useBuildPath } from './routing';
const buildPath = useBuildPath();
// ✅ Correct: TS knows 'posts' is a valid route and 'id' is a required param.
const profilePath = buildPath('posts', { id: '123' });
// ❌ Compile-Time Error: 'userId' is not a valid parameter name.
// const invalidPath = buildPath('posts', { userId: '123' });
// ❌ Compile-Time Error: 'foo' is not a defined route.
// const nonExistentPath = buildPath('foo', { id: '123' });
This immediate feedback prevents bugs and makes refactoring safe and predictable.
Explore interactive examples on CodeSandbox to see @route-weaver/react
in action.
- Basic Setup: Link to CodeSandbox
- Advanced Usage with Authorization: [Link to CodeSandbox] (coming soon)
Contributions are welcome! Please see the main CONTRIBUTING.md file for details.
MIT