Routing Stable
VeloxKit ships with @velox/router — a named-route history-stack router built for native desktop apps. It uses the same mental model as React Navigation: a stack of { name, params } entries with no URLs.
Desktop apps have no URL bar, so file-based URL routing is not a good fit. @velox/router uses named routes — fast, simple, and works offline.
Install
npm install @velox/routerSetup
Declare routes with <Route> components inside <Router>:
import { Router, Route } from '@velox/router'
import HomeScreen from './screens/HomeScreen'
import DetailScreen from './screens/DetailScreen'
import SettingsScreen from './screens/SettingsScreen'
export default function App() {
return (
<Router initialRoute="home">
<Route name="home" component={HomeScreen} />
<Route name="detail" component={DetailScreen} />
<Route name="settings" component={SettingsScreen} />
</Router>
)
}initialRoute sets the first screen. If omitted, the first declared <Route> is used.
Navigating between screens
import { useNavigate } from '@velox/router'
function HomeScreen() {
const navigate = useNavigate()
return (
<Pressable onPress={() => navigate('detail', { id: 42 })}>
<Text>Open detail</Text>
</Pressable>
)
}navigate(name, params?, opts?):
| Call | Effect |
|---|---|
navigate('detail', { id: 42 }) | Push detail screen with params |
navigate('back') | Pop current screen (back) |
navigate('home', {}, { replace: true }) | Replace current screen |
Reading route params
import { useRoute } from '@velox/router'
function DetailScreen() {
const { name, params, canGoBack } = useRoute()
return (
<View style={{ flex: 1, padding: 24 }}>
<Text>Route: {name}</Text>
<Text>ID: {params.id}</Text>
</View>
)
}useRoute() returns:
| Field | Type | Description |
|---|---|---|
name | string | null | Current route name |
params | object | Params passed to navigate() |
canGoBack | boolean | true when history stack has more than one entry |
Back button
import { useNavigate, useRoute } from '@velox/router'
import { Pressable, Text } from 'veloxkit'
function BackButton() {
const navigate = useNavigate()
const { canGoBack } = useRoute()
if (!canGoBack) return null
return (
<Pressable onPress={() => navigate('back')}>
<Text>← Back</Text>
</Pressable>
)
}Active route highlighting
import { useRoute, useNavigate } from '@velox/router'
function NavItem({ route, label }: { route: string; label: string }) {
const { name } = useRoute()
const navigate = useNavigate()
const isActive = name === route
return (
<Pressable onPress={() => navigate(route)}>
<Text style={{ color: isActive ? '#00A878' : '#A0A0B2' }}>{label}</Text>
</Pressable>
)
}Sidebar layout with router
A common pattern for desktop apps — persistent sidebar navigation alongside a routed content area:
import { Router, Route, useNavigate, useRoute } from '@velox/router'
import { View, Text, Pressable } from 'veloxkit'
function SidebarItem({ route, label }: { route: string; label: string }) {
const { name } = useRoute()
const navigate = useNavigate()
return (
<Pressable
onPress={() => navigate(route)}
style={{
paddingVertical: 10,
paddingHorizontal: 16,
backgroundColor: name === route ? '#00A87820' : 'transparent',
borderRadius: 6,
}}
>
<Text style={{ color: name === route ? '#00A878' : '#ccc' }}>{label}</Text>
</Pressable>
)
}
function Layout() {
return (
<View style={{ flex: 1, flexDirection: 'row' }}>
{/* Sidebar */}
<View style={{ width: 200, backgroundColor: '#1a1a24', padding: 12 }}>
<SidebarItem route="home" label="Home" />
<SidebarItem route="notes" label="Notes" />
<SidebarItem route="settings" label="Settings" />
</View>
{/* Content — Router renders the active screen here */}
<View style={{ flex: 1 }}>
<Router initialRoute="home">
<Route name="home" component={HomeScreen} />
<Route name="notes" component={NotesScreen} />
<Route name="settings" component={SettingsScreen} />
</Router>
</View>
</View>
)
}TypeScript
Type your params with a route map:
type Routes = {
home: {}
detail: { id: number }
settings: {}
}Then narrow params in screens:
function DetailScreen() {
const { params } = useRoute()
const { id } = params as Routes['detail']
// ...
}Full API
| Export | Description |
|---|---|
<Router initialRoute?> | Router container. Renders the active screen. |
<Route name component> | Route declaration. Always renders null itself. |
useNavigate() | Returns navigate(name, params?, opts?) |
useRoute() | Returns { name, params, canGoBack } |