Skip to main content

Overview

The Routable trait and #[derive(Routable)] macro enable type-safe routing in Dioxus. Routes are defined as enum variants that map to URL patterns.

Deriving Routable

Use the #[derive(Routable)] macro to implement routing for an enum:
use dioxus::prelude::*;

#[derive(Clone, Routable, PartialEq, Debug)]
enum Route {
    #[route("/")]
    Home {},
    
    #[route("/blog/:id")]
    BlogPost { id: usize },
    
    #[route("/edit?:id")]
    Edit { id: usize },
    
    #[route("/hashtag/#:tag")]
    Hashtag { tag: String },
}

Route Attributes

#[route("path")]

Defines the URL pattern for a route variant.

Static Routes

#[route("/about")]
About {},

Dynamic Segments

Capture path segments as typed parameters:
#[route("/user/:id")]
User { id: usize },

Catch-All Segments

Capture multiple path segments:
#[route("/files/:..path")]
Files { path: Vec<String> },

Query Parameters

Parse URL query strings:
#[route("/search?:query")]
Search { query: String },

#[route("/results?:page&:limit")]
Results { 
    page: usize,
    limit: usize,
},

Hash Fragments

Capture URL hash fragments:
#[route("/docs/#:section")]
Docs { section: String },

#[nest("prefix")]

Group routes under a common path prefix:
#[derive(Clone, Routable, PartialEq)]
enum Route {
    #[nest("/dashboard")]
        #[route("/")]
        Dashboard {},
        
        #[route("/settings")]
        Settings {},
    #[end_nest]
    
    #[route("/")]
    Home {},
}

#[layout(Component)]

Wrap nested routes in a layout component:
#[derive(Clone, Routable, PartialEq)]
enum Route {
    #[nest("/admin")]
        #[layout(AdminLayout)]
            #[route("/")]
            AdminHome {},
            
            #[route("/users")]
            AdminUsers {},
        #[end_layout]
    #[end_nest]
    
    #[route("/")]
    Home {},
}

#[component]
fn AdminLayout() -> Element {
    rsx! {
        div { class: "admin-layout",
            nav { "Admin Menu" }
            Outlet::<Route> {}
        }
    }
}

Route Components

Each route variant must have a corresponding component with the same name:
#[derive(Clone, Routable, PartialEq)]
enum Route {
    #[route("/user/:id")]
    User { id: usize },
}

// Component must match the route variant name
#[component]
fn User(id: usize) -> Element {
    rsx! {
        h1 { "User {id}" }
    }
}
Route parameters are automatically passed as component props.

Type Requirements

Path Segments

Types used in path segments must implement:
  • FromStr - Parse from URL string
  • Display - Format back to URL string
  • Default - Provide fallback if parsing fails
#[derive(Default, Clone, PartialEq, Debug)]
struct UserId(usize);

impl std::str::FromStr for UserId {
    type Err = std::num::ParseIntError;
    
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(UserId(s.parse()?))
    }
}

impl std::fmt::Display for UserId {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

Query Parameters

Query parameters must implement:
  • FromStr + Default for single parameters
  • From<&str> for spread queries (?:..query)

Catch-All Segments

Catch-all segments must implement:
  • FromIterator<String> - Collect from segments
  • ToRouteSegments - Format back to path

Routable Trait

The Routable trait is automatically implemented by the derive macro. It provides:

Methods

render
fn(&self, level: usize) -> Element
Render the route at the given nesting level.
is_child_of
fn(&self, other: &Self) -> bool
Check if this route is a child of another route.
parent
fn(&self) -> Option<Self>
Get the parent route, if any.
static_routes
fn() -> Vec<Self>
Get all static routes (routes without dynamic segments).

Usage Example

let route = Route::BlogPost { id: 42 };
let parent = route.parent(); // Returns Route::BlogList

let blog_list = Route::BlogList {};
let blog_post = Route::BlogPost { id: 1 };
assert!(blog_post.is_child_of(&blog_list));

let static_routes = Route::static_routes();
// Returns all routes without parameters

Conversion Traits

Routes implement FromStr and Display for URL conversion:
use std::str::FromStr;

// Parse from URL string
let route = Route::from_str("/blog/42").unwrap();
assert_eq!(route, Route::BlogPost { id: 42 });

// Convert to URL string
let url = Route::BlogPost { id: 42 }.to_string();
assert_eq!(url, "/blog/42");

Source

View the source code: packages/router/src/routable.rs

Build docs developers (and LLMs) love