Router

Router is Fission's basic path-matching widget.
A beginner-friendly way to think about it is this: your app state stores a path string such as /inbox or /projects/42, and Router decides which screen widget to return for that string. It does not read the browser location on its own. It does not push history entries for you. It does not own a hidden navigation stack. It simply turns explicit route state into explicit user interface.
That design is important for cross-platform work. The same current_path state can drive a browser location, a desktop sidebar selection, or a mobile back-stack model that you choose to represent as paths. The shell differences stay outside the routing widget. The Router just matches the current string and builds the corresponding screen.

Example

use fission::prelude::*;

let selected_project_id = view.state().selected_project_id.clone();
let router = Router {
    current_path: view.state().current_path.clone(),
    routes: vec![
        Route {
            path: "/projects".into(),
            page: ProjectList.into(),
        },
        Route {
            path: "/projects/:id".into(),
            page: ProjectDetail { id: selected_project_id }.into(),
        },
    ],
    not_found: Some(Text::new("Page not found").into()),
}
.into();
In a real app, some other widget dispatches a navigation action, a reducer updates state.current_path, and the next build chooses a different route.

Field table

Field
Type
Meaning
Notes / default behavior
current_path
String
The path string to match this frame.
Usually lives in GlobalState so reducers can update it explicitly.
routes
Vec<Route>
Ordered list of route patterns and screen widgets.
The router returns the first matching route. Order matters.
not_found
Option<Widget>
Fallback widget when no route matches.
If omitted, the router renders a plain 404: {current_path} text node.

Matching behavior

The current matcher is deliberately small:
/users/:id matches /users/123
/users/:id does not match /users/123/details
empty leading and trailing slashes are ignored during matching
This small contract makes routing easy to test. If a path renders the wrong screen, you only need to inspect the current path string and the ordered route list.

State ownership across platforms

On web, you will usually want some outer integration that keeps current_path in sync with the browser location and history. On desktop, the same state may come from a sidebar click, command palette action, or menu item. On mobile, it may mirror a back-navigation model that you still choose to express as paths.
The key point is that Router does not hide those differences. It lets you keep one app model and connect each shell-specific navigation source to that model in the place where it belongs.

Specific advice

Keep current_path normalized. Pick one format for trailing slashes, slug casing, and identifier encoding so reducers and tests do not have to guess what a valid path looks like.
Also keep route changes explicit. If a button means "go to /settings," dispatch a navigation action that updates state. Avoid scattering manual string mutations through unrelated reducers.

Production checklist

For Router, review the fields that change behavior before treating the widget as finished: current_path, routes, not_found. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
If this widget appears inside an interactive flow, keep the surrounding action binding in the parent component and test that the flow still has one clear reducer path.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same Router setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
Route, RouteParams, Link, and Overview.
Fission
A cross-platform, GPU-accelerated user interface framework for Rust. MIT licensed.
Copyright (c) 2026 Fission
Ready to use today. Widget APIs are expected to remain stable; some runtime and shell APIs may change before 1.0.0.
Fission 0.7.0