HTML templates, static files, and server-side rendering.
Build full web applications with template rendering, variable interpolation, loops, conditionals, static file serving, and redirects. Compiles to Axum HTML responses + tower-http.
Every function in the std.html module.
Loads an HTML template file and replaces template markers with data values. Supports {{variable}} interpolation, {{#each array}} loops, and {{#if condition}} conditionals.
data := { "title": "My Page", "items": ["a", "b"] }
content := html.template("templates/page.html", data)
Returns an HTTP response with Content-Type: text/html and the given HTML content as the body.
content := html.template("templates/page.html", data)
html.render(content) // returns Response with text/html
Serves static files (CSS, JS, images, fonts) from the specified directory. Files are served with correct MIME types and caching headers.
server.get("/static") => fn(req) -> Response {
html.serve_static("public/")
}
Returns a 302 redirect response to the specified URL. Use for URL migrations, post-form-submit redirects, or shortlinks.
server.get("/old-page") => fn(req) -> Response {
html.redirect("/")
}
Handlebars-inspired template markers.
<h1>{{heading}}</h1>
<p>{{message}}</p>
Replaced with the corresponding value from the data map.
{{#each items}}
<li>{{name}} — ${{price}}</li>
{{/each}}
Iterates over arrays. Inner properties available directly.
{{#if show_footer}}
<footer>© 2026</footer>
{{/if}}
Renders block only if value is truthy.
{{#if in_stock}}
<span class="green">Available</span>
{{else}}
<span class="red">Sold Out</span>
{{/if}}
Fallback content when condition is false.
Multi-page web app with templates, static files, and redirects.
module main
use std.http
use std.html
fn main() {
server := http.new(port: 8080)
// Homepage — template with variables
server.get("/") => fn(req) -> Response {
data := {
"title": "My App",
"heading": "Welcome",
"show_footer": true
}
content := html.template("templates/index.html", data)
html.render(content)
}
// Items page — template with {{#each}} loop
server.get("/items") => fn(req) -> Response {
data := {
"title": "Products",
"items": [
{ "name": "Widget", "price": "9.99" },
{ "name": "Gadget", "price": "19.99" }
]
}
content := html.template("templates/items.html", data)
html.render(content)
}
// Redirect old URLs
server.get("/old-page") => fn(req) -> Response {
html.redirect("/")
}
// Static files: CSS, JS, images
server.get("/static") => fn(req) -> Response {
html.serve_static("public/")
}
server.start()
}
What the compiler produces for HTML operations.
Transpiled Output (simplified)use axum::response::Html;
use tower_http::services::ServeDir;
// html.template("templates/page.html", data)
let template = std::fs::read_to_string("templates/page.html").unwrap();
let rendered = template
.replace("{{title}}", &data["title"])
.replace("{{heading}}", &data["heading"]);
// + loop/conditional expansion at compile time
// html.render(content)
Html(rendered)
// html.redirect("/")
Redirect::to("/")
// html.serve_static("public/")
Router::new().nest_service("/static", ServeDir::new("public/"))