Router: Page
Declares a page handler.
Use #[page] without a path string with module routing. The enclosing module determines the URL. A path starting with ./ extends the module path. An absolute path, such as #[page("/about")], chooses the URL independently of the module tree and requires separate registration.
A page serves GET by default. To serve other methods, name them in the attribute, using the same forms as #[route]: a single method (#[page(POST)]), a bracketed list ([GET, POST]), or * for every method.
Path strings follow the Path syntax.
module_router! registers module-derived handlers. For explicit paths, pass the function name to RouterBuilder::page or use discover.
Handler signature
The function must be async and return a Result containing a View. It may take cx: &Cx and one body parameter implementing FromRequest. Both are optional and may appear in either order. The body parameter may use a pattern such as Json(input): Json<T>.
Examples
Module-derived path (in src/app/about.rs under module_router!(), this serves /about):
#[page]
async fn about() -> Result<impl View> {
Ok(view! { <h1>"About"</h1> })
}
Explicit path:
#[page("/users/{id}")]
async fn user_profile() -> Result<impl View> {
Ok(view! { <h1>"User profile"</h1> })
}
Path below the module (in src/app/settings.rs under module_router!(), this serves /settings/export):
#[page("./export")]
async fn export() -> Result<impl View> {
Ok(view! { <h1>"Export"</h1> })
}
Declaring a method (a form submission answered with a rendered view):
// src/app/signup.rs
#[page(POST)]
async fn signup(Form(input): Form<Signup>) -> Result<impl View> {
Ok(view! { <h1>"Welcome, " (input.email)</h1> })
}
Reading a request body:
// src/app/contact.rs
#[page]
async fn contact(Form(input): Form<Search>) -> Result<impl View> {
Ok(view! { <main>"searching for " (input.q)</main> })
}
Pages as components
A page doubles as a component: calling it inside view! renders it inline. A page that reads a request body takes the already-parsed value as a body prop instead of parsing the request.
// src/app/preview.rs
#[page]
async fn preview() -> Result<impl View> {
let query = Search {
q: String::from("hearth"),
};
Ok(view! {
contact::contact(body: Form(query))
})
}