Derive Macro dioxus_router_macro::Routable

source ·
#[derive(Routable)]
{
    // Attributes available to this derive:
    #[route]
    #[nest]
    #[end_nest]
    #[layout]
    #[end_layout]
    #[redirect]
    #[child]
}
Expand description

Derives the Routable trait for an enum of routes

Each variant must:

  1. Be struct-like with {}’s
  2. Contain all of the dynamic parameters of the current and nested routes
  3. Have a #[route("route")] attribute

Route Segments:

  1. Static Segments: “/static”
  2. Dynamic Segments: “/:dynamic” (where dynamic has a type that is FromStr in all child Variants)
  3. Catch all Segments: “/:..segments” (where segments has a type that is FromSegments in all child Variants)
  4. Query Segments: “/?:..query” (where query has a type that is FromQuery in all child Variants) or “/?:query&:other_query” (where query and other_query has a type that is FromQueryArgument in all child Variants)

Routes are matched:

  1. By there specificity this order: Query Routes (“/?:query”), Static Routes (“/route”), Dynamic Routes (“/:route”), Catch All Routes (“/:..route”)
  2. By the order they are defined in the enum

All features:

#[rustfmt::skip]
#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
    // Define routes with the route macro. If the name of the component is not the same as the variant, you can specify it as the second parameter
    #[route("/", IndexComponent)]
    Index {},
    // Nests with parameters have types taken from child routes
    // Everything inside the nest has the added parameter `user_id: usize`
    #[nest("/user/:user_id")]
        // All children of layouts will be rendered inside the Outlet in the layout component
        // Creates a Layout UserFrame that has the parameter `user_id: usize`
        #[layout(UserFrame)]
            // If there is a component with the name Route1, you do not need to pass in the component name
            #[route("/:dynamic?:query")]
            Route1 {
                // The type is taken from the first instance of the dynamic parameter
                user_id: usize,
                dynamic: usize,
                query: String,
            },
            #[route("/hello_world")]
            // You can opt out of the layout by using the `!` prefix
            #[layout(!UserFrame)]
            Route2 { user_id: usize },
        // End layouts with #[end_layout]
        #[end_layout]
    // End nests with #[end_nest]
    #[end_nest]
    // Redirects take a path and a function that takes the parameters from the path and returns a new route
    #[redirect("/:id/user", |id: usize| Route::Route3 { dynamic: id.to_string()})]
    #[route("/:dynamic")]
    Route3 { dynamic: String },
    #[child]
    NestedRoute(NestedRoute),
}

§#[route("path", component)]

The #[route] attribute is used to define a route. It takes up to 2 parameters:

  • path: The path to the enum variant (relative to the parent nest)
  • (optional) component: The component to render when the route is matched. If not specified, the name of the variant is used

Routes are the most basic attribute. They allow you to define a route and the component to render when the route is matched. The component must take all dynamic parameters of the route and all parent nests. The next variant will be tied to the component. If you link to that variant, the component will be rendered.

#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
    // Define routes that renders the IndexComponent
    // The Index component will be rendered when the route is matched (e.g. when the user navigates to /)
    #[route("/", Index)]
    Index {},
}

§#[redirect("path", function)]

The #[redirect] attribute is used to define a redirect. It takes 2 parameters:

  • path: The path to the enum variant (relative to the parent nest)
  • function: A function that takes the parameters from the path and returns a new route
#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
    // Redirects the /:id route to the Index route
    #[redirect("/:id", |_: usize| Route::Index {})]
    #[route("/", Index)]
    Index {},
}

Redirects allow you to redirect a route to another route. The function must take all dynamic parameters of the route and all parent nests.

§#[nest("path")]

The #[nest] attribute is used to define a nest. It takes 1 parameter:

  • path: The path to the nest (relative to the parent nest)

Nests effect all nests, routes and redirects defined until the next #[end_nest] attribute. All children of nests are relative to the nest route and must include all dynamic parameters of the nest.

#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
    // Nests all child routes in the /blog route
    #[nest("/blog")]
        // This is at /blog/:id
        #[redirect("/:id", |_: usize| Route::Index {})]
        // This is at /blog
        #[route("/", Index)]
        Index {},
}

§#[end_nest]

The #[end_nest] attribute is used to end a nest. It takes no parameters.

#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
    #[nest("/blog")]
        // This is at /blog/:id
        #[redirect("/:id", |_: usize| Route::Index {})]
        // This is at /blog
        #[route("/", Index)]
        Index {},
    // Ends the nest
    #[end_nest]
    // This is at /
    #[route("/")]
    Home {},
}

§#[layout(component)]

The #[layout] attribute is used to define a layout. It takes 1 parameter:

  • component: The component to render when the route is matched. If not specified, the name of the variant is used

The layout component allows you to wrap all children of the layout in a component. The child routes are rendered in the Outlet of the layout component. The layout component must take all dynamic parameters of the nests it is nested in.

#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
    #[layout(BlogFrame)]
        #[redirect("/:id", |_: usize| Route::Index {})]
        // Index will be rendered in the Outlet of the BlogFrame component
        #[route("/", Index)]
        Index {},
}

§#[end_layout]

The #[end_layout] attribute is used to end a layout. It takes no parameters.

#[derive(Clone, Debug, PartialEq, Routable)]
enum Route {
    #[layout(BlogFrame)]
        #[redirect("/:id", |_: usize| Route::Index {})]
        // Index will be rendered in the Outlet of the BlogFrame component
        #[route("/", Index)]
        Index {},
    // Ends the layout
    #[end_layout]
    // This will be rendered standalone
    #[route("/")]
    Home {},
}