Standard Library

📄 std.html

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.

API Reference

Every function in the std.html module.

html.template(path: string, data: map) → string

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)

html.render(content: string) → Response

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

html.serve_static(path: string) → Response

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/")
}

html.redirect(url: string) → Response

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("/")
}

Template Syntax

Handlebars-inspired template markers.

Variables

<h1>{{heading}}</h1>
<p>{{message}}</p>

Replaced with the corresponding value from the data map.

Loops

{{#each items}}
  <li>{{name}} — ${{price}}</li>
{{/each}}

Iterates over arrays. Inner properties available directly.

Conditionals

{{#if show_footer}}
  <footer>© 2026</footer>
{{/if}}

Renders block only if value is truthy.

If/Else

{{#if in_stock}}
  <span class="green">Available</span>
{{else}}
  <span class="red">Sold Out</span>
{{/if}}

Fallback content when condition is false.

Complete Example

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()
}

Generated Rust

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/"))