Using Template Engines

Salvo does not come with any built-in template engine, as preferences for template engine styles vary from person to person.

At its core, a template engine is simply: data + template = string.

Therefore, as long as the final string can be rendered, any template engine can be supported.

For example, support for askama:

main.rs
Cargo.toml
templates/hello.html
use askama::Template;
use salvo::prelude::*;

#[derive(Template)]
#[template(path = "hello.html")]
struct HelloTemplate<'a> {
    name: &'a str,
}

#[handler]
async fn hello(req: &mut Request, res: &mut Response) {
    let hello_tmpl = HelloTemplate {
        name: req.param::<&str>("name").unwrap_or("World"),
    };
    res.render(Text::Html(hello_tmpl.render().unwrap()));
}

#[tokio::main]
async fn main() {
    tracing_subscriber::fmt().init();

    let router = Router::with_path("{name}").get(hello);
    let acceptor = TcpListener::new("0.0.0.0:8698").bind().await;
    Server::new(acceptor).serve(router).await;
}

Note: For projects that are not particularly complex, we highly recommend adopting a frontend-backend separation approach. Use more flexible and ecosystem-rich UI frameworks (such as React, Vue, Svelte, etc.) to build the frontend, with Salvo serving as the backend API service. This approach leads to higher development efficiency, clearer responsibilities between frontend and backend, and better aligns with modern web application development trends.