DocsRendering and delivery
Metadata & SEO
Resolve route-aware titles, descriptions, canonical URLs, robots directives, and social cards on the server.
One metadata owner per route
Root layouts provide site defaults, nested layouts refine a section, and the page provides the most specific values. Rahti merges that chain on the server and writes the final managed tags into the document head.
use crate::rahti::Metadata;
pub fn metadata() -> Metadata {
Metadata::new()
.title("Billing")
.description("Manage invoices and payment methods")
.canonical("https://example.com/account/billing")
.open_graph("type", "website")
.twitter("card", "summary")
}Merge order and titles
| Source | Priority |
|---|---|
| root layout | Site defaults such as default_title, description, and social defaults. |
| nested layouts | Section-specific values and title templates. |
| page metadata() | Static values for the concrete page. |
| Page::new metadata | Request-specific values with the highest priority. |
title_template("{title} | Acme") formats an ordinary title. absolute_title bypasses inherited templates, while default_title is used only when descendants provide no title.
Dynamic metadata
When metadata depends on a path, database record, or session, return a Page. The value belongs to that response, so concurrent requests cannot see one another's titles.
pub async fn page(Path(slug): Path<String>) -> Page<Html> {
let post = load_post(&slug).await?;
Ok(Page::new(
html! { <article><h1>@{&post.title}</h1></article> },
Metadata::new()
.title(&post.title)
.description(&post.summary),
))
}Supported fields
| Builder | Rendered purpose |
|---|---|
| title / default_title / absolute_title | The document title. |
| description / keywords / meta | Named metadata fields. |
| canonical | The public canonical URL; supply an absolute URL for crawlers. |
| robots | Index and follow directives through Robots. |
| open_graph / twitter | Social preview fields; omit the og: or twitter: prefix. |
Client navigation
Every full response already contains the final tags, so SEO does not depend on JavaScript. During same-layout SPA navigation, the scaffolded client entry copies the next route's managed metadata into document.head. Preserve that synchronization if you customize public/js/main.js.
