https://github.com/uhyo/funstack-router
Router library based on Navigation API. In explocation of a router without History API legacy
https://github.com/uhyo/funstack-router
react router
Last synced: 4 months ago
JSON representation
Router library based on Navigation API. In explocation of a router without History API legacy
- Host: GitHub
- URL: https://github.com/uhyo/funstack-router
- Owner: uhyo
- License: mit
- Created: 2025-12-10T14:03:09.000Z (7 months ago)
- Default Branch: master
- Last Pushed: 2026-02-18T06:38:28.000Z (5 months ago)
- Last Synced: 2026-02-18T10:23:31.048Z (5 months ago)
- Topics: react, router
- Language: TypeScript
- Homepage: https://router.funstack.work/
- Size: 1.11 MB
- Stars: 37
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# FUNSTACK Router

A modern React router built on the [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API).
> **Warning**
> This project is in early development and is not ready for production use. APIs may change without notice.
## Features
- **Navigation API based** - Uses the modern Navigation API instead of the History API
- **Native `` tags just work** - No special `` component needed; use standard HTML links
- **Object-based routes** - Define routes as plain JavaScript objects
- **Nested routing** - Support for layouts and nested routes with ``
- **Type-safe** - Full TypeScript support
- **Lightweight** - Minimal API surface
## Installation
```bash
npm install @funstack/router
```
## Development
This is a pnpm monorepo. To set up the development environment:
```bash
# Install dependencies
pnpm install
# Build the router package
pnpm build
# Run the example app
pnpm --filter funstack-router-example dev
# Run tests
pnpm test
```
### Packages
- `packages/router` - The main `@funstack/router` library
- `packages/example` - Example application
## Quick Start
```tsx
import { Router, Outlet } from "@funstack/router";
import type { RouteDefinition } from "@funstack/router";
function Layout() {
return (
);
}
function Home() {
return
Home
;
}
function Users() {
return
Users
;
}
function UserDetail({ params }: { params: { id: string } }) {
return
User {params.id}
;
}
const routes: RouteDefinition[] = [
{
path: "/",
component: Layout,
children: [
{ path: "", component: Home },
{ path: "users", component: Users },
{ path: "users/:id", component: UserDetail },
],
},
];
function App() {
return ;
}
```
## API Reference
### Components
#### ``
The root component that provides routing context.
```tsx
```
| Prop | Type | Description |
| ------------ | -------------------- | -------------------------------------------------------------------- |
| `routes` | `RouteDefinition[]` | Array of route definitions |
| `onNavigate` | `OnNavigateCallback` | Optional callback invoked before navigation is intercepted |
| `fallback` | `FallbackMode` | Fallback mode when Navigation API is unavailable (default: `"none"`) |
#### ``
Renders the matched child route. Used in layout components.
```tsx
function Layout() {
return (
...
);
}
```
### Hooks
#### `useNavigate()`
Returns a function for programmatic navigation.
```tsx
const navigate = useNavigate();
// Basic navigation
navigate("/users");
// With options
navigate("/users", { replace: true, state: { from: "home" } });
```
#### `useLocation()`
Returns the current location.
```tsx
const location = useLocation();
// { pathname: "/users", search: "?page=1", hash: "#section" }
```
#### `useParams()`
Returns the current route's path parameters. Note that route components also receive `params` as a prop, so this hook is mainly useful for non-route components that need access to params.
```tsx
// Route: /users/:id
const { id } = useParams<{ id: string }>();
```
#### `useSearchParams()`
Returns and allows updating URL search parameters.
```tsx
const [searchParams, setSearchParams] = useSearchParams();
// Read
const page = searchParams.get("page");
// Update
setSearchParams({ page: "2" });
// Update with function
setSearchParams((prev) => {
prev.set("page", "2");
return prev;
});
```
### Types
#### `RouteDefinition`
Route components receive a `params` prop with the matched path parameters. Use the `route()` helper for type-safe route definitions:
```typescript
import { route } from "@funstack/router";
// Route without loader - component receives params prop
route({
path: "users/:id",
component: UserDetail, // receives { params: { id: string } }
});
// Route with loader - component receives both data and params props
route({
path: "users/:id",
loader: async ({ params }) => fetchUser(params.id),
component: UserDetail, // receives { data: Promise, params: { id: string } }
});
```
You can also define routes as plain objects (without type inference):
```typescript
type RouteDefinition = {
path: string;
component?: React.ComponentType<{ params: Record }>;
children?: RouteDefinition[];
};
```
#### `Location`
```typescript
type Location = {
pathname: string;
search: string;
hash: string;
};
```
#### `NavigateOptions`
```typescript
type NavigateOptions = {
replace?: boolean;
state?: unknown;
};
```
## Path Patterns
FUNSTACK Router uses the [URLPattern API](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) for path matching.
| Pattern | Example | Matches |
| ------------ | -------------- | --------------- |
| `/users` | `/users` | Exact match |
| `/users/:id` | `/users/123` | Named parameter |
| `/files/*` | `/files/a/b/c` | Wildcard |
## Browser Support
The Navigation API is supported in:
- Chrome 102+
- Edge 102+
- Firefox 147+
- Safari 26.2+
- Opera 88+
## License
MIT