← All Workshops

MudEngine Part 1: Requirements

Step 13 / 19

Dioxus Router

The router provides client-side navigation without full page reloads. All routes are defined as a single Rust enum, giving you compile-time guarantees that every link points to a valid route.

🧭 Enum-based routing

Routes are declared as an enum deriving Routable:

enum Route {
    #[route("/")]
    Home {},
    #[route("/blog/:id")]
    BlogPost { id: u32 },
    #[route("/blog/:id/:slug")]
    BlogPostWithSlug { id: u32, slug: String },
}

Each variant's fields become dynamic URL segments (:id, :slug). The router parses the current URL, matches it against the enum, and passes extracted values as typed arguments — no string parsing needed.

Navigation is done via the use_navigator hook or the Link component. Internally the router uses the History API (pushState/replaceState) so the browser back/forward buttons work naturally.

📐 Layouts and Outlet

Layouts let you wrap a group of routes with shared UI. A layout is a component that renders an Outlet where the matched child route is injected:

#[derive(Routable)]
enum Route {
    #[layout(Navbar)]
        #[route("/")]
        Home {},
        #[route("/blog")]
        BlogIndex {},
        #[route("/blog/:id")]
        BlogPost { id: u32 },
}

The Navbar component renders navigation chrome and an Outlet<Route> placeholder. When the user navigates from / to /blog/42, only the outlet content re-renders — the navbar stays mounted. Layouts can be nested arbitrarily.

⚡ Server Functions with the router

When combined with Fullstack, the router integrates with server functions seamlessly. A #[post("/api/...")] function generates both the client-side fetch call and the server endpoint. In SSR mode, the router can call server functions during the initial render via use_server_future, which serializes the result into the HTML so the client never makes a separate API request.

Step 13 / 19