Routing
flexium/router is a tiny client-side router. Define routes declaratively with <Routes> + <Route>, navigate with <Link>, read state with useRouter().
Basic setup
import { Routes, Route, Link } from 'flexium/router'
function Home() { return <h1>Home</h1> }
function About() { return <h1>About</h1> }
function App() {
return (
<>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</Routes>
</>
)
}Clicking <Link> calls history.pushState and updates the route signal. Browser back/forward work automatically.
Dynamic params
<Route path="/users/:id" component={UserPage} />
function UserPage() {
const { params } = useRouter()
return <h1>User #{params.id}</h1>
}Multiple params:
<Route path="/posts/:category/:slug" component={Post} />
// /posts/tech/hello-world → params = { category: 'tech', slug: 'hello-world' }Catch-all
<Route path="*" component={NotFound} />
// or
<Route path="/docs/*" component={Docs} />Nested routes
Use <Outlet /> for layout patterns:
import { Routes, Route, Outlet, Link } from 'flexium/router'
function DashboardLayout() {
return (
<div class="dashboard">
<aside>
<Link to="/dashboard">Home</Link>
<Link to="/dashboard/settings">Settings</Link>
</aside>
<main>
<Outlet />
</main>
</div>
)
}
<Routes>
<Route path="/dashboard" component={DashboardLayout}>
<Route path="/" component={DashboardHome} />
<Route path="/settings" component={Settings} />
</Route>
</Routes>The layout component wraps every child route's content via <Outlet />.
Programmatic navigation
import { useRouter } from 'flexium/router'
function LoginForm() {
const { navigate } = useRouter()
async function submit() {
await login(...)
navigate('/dashboard') // SPA-style, no full page reload
}
}navigate(path, options?):
options.replace: true— replaces history entry instead of pushingoptions.state— passes state via History API
Reading route state
function Page() {
const { location, params, navigate } = useRouter()
// location.pathname — current URL path
// location.search — query string
// params — captured route params (object)
// navigate(path) — programmatic navigation
}Route guards
Restrict access via beforeEnter:
function isLoggedIn() { /* ... */ }
<Route
path="/admin"
component={AdminDashboard}
beforeEnter={(params) => {
if (!isLoggedIn()) {
navigate('/login')
return false // skip rendering
}
return true
}}
/>Query strings
useRouter().location.search gives you the raw ?foo=bar string. Parse with URLSearchParams:
const { location } = useRouter()
const params = new URLSearchParams(location.search)
const page = Number(params.get('page') ?? 1)Link vs anchor
<Link to="/x"> is the SPA-style navigation. Renders as <a href="/x"> but intercepts the click and calls navigate('/x').
Use plain <a href="..."> for external links or when you want a full page reload.
Performance
The router uses signal-based path matching — only components inside <Routes> re-render on navigation. Other parts of the tree (header, footer, sidebar) stay untouched.
Next
→ Styling — flexium/css atomic styles.