Install the package using your preferred package manager:
npm install @funstack/router
# or
pnpm add @funstack/router
# or
yarn add @funstack/router@funstack/router ships with an Agent skill that gives your coding assistant (Claude Code, Cursor, GitHub Copilot, etc.) knowledge about the router's API and best practices. Run:
npx -p @funstack/router funstack-router-skill-installer
# or
pnpm dlx --package @funstack/router funstack-router-skill-installer
# or
yarn dlx -p @funstack/router funstack-router-skill-installerThe installer will guide you through setting up the skill for your preferred AI agent. Alternatively, if you prefer npx skills, you can install it with:
npx skills add uhyo/funstack-routerFUNSTACK Router uses the Navigation API which is supported in Chrome 102+, Edge 102+, Firefox 147+, Safari 26.2+.
Create your routes using the route helper function and render them with the Router component:
import { Router, route, Outlet } from "@funstack/router";
// Define your page components
function Home() {
return <h1>Welcome Home</h1>;
}
function About() {
return <h1>About Us</h1>;
}
function Layout() {
return (
<div>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<Outlet />
</div>
);
}
// Define your routes
const routes = [
route({
path: "/",
component: Layout,
children: [
route({ path: "/", component: Home }),
route({ path: "/about", component: About }),
],
}),
];
// Render the router
function App() {
return <Router routes={routes} />;
}Define dynamic segments in your paths using the :param syntax. Route components receive parameters via the params prop, which is fully typed based on the path pattern:
import { route } from "@funstack/router";
function UserProfile({ params }: { params: { userId: string } }) {
return <h1>User: {params.userId}</h1>;
}
const routes = [
route({
path: "/users/:userId",
component: UserProfile,
}),
];Use the loader option to fetch data before rendering a route. The component receives both data (from the loader) and params (from the URL) as props:
import { route } from "@funstack/router";
interface User {
id: string;
name: string;
}
function UserProfilePage({
data,
params,
}: {
data: Promise<User>;
params: { userId: string };
}) {
return (
<Suspense fallback={<div>Loading...</div>}>
<UserProfile data={data} params={params} />
</Suspense>
);
}
function UserProfile({
data,
params,
}: {
data: Promise<User>;
params: { userId: string };
}) {
const user = use(data);
return (
<div>
<h1>{user.name}</h1>
<p>User ID: {params.userId}</p>
</div>
);
}
const userRoute = route({
path: "/users/:userId",
component: UserProfilePage,
loader: async ({ params }): Promise<User> => {
const response = await fetch(`/api/users/${params.userId}`);
return response.json();
},
});