RatMinimal web framework

Main shell

main.rat at the project root is the document shell: the header, footer, nav, and anything every page needs. Its > page block renders on every request. Wherever it places <page>, the current route's > page body inlines.

A minimal shell

main.rat

The page tag is reserved. The renderer treats it as a slot and fills it with whatever the matched route produces. Everything around it renders on every request, with access to the project-wide server state.

# main.rat
> server
title: 'My site'

> page
<header>
    <a href['/']> Home
<main>
    <page>
<footer>
    &copy; 2026

Shell server state is shared

Every page sees it

Names declared in main.rat's > server block are in scope for every page render. Use it for the site title, the current user, anything the layout itself needs to display.

# main.rat
> server
site_name: 'Rat docs'
user: auth.user

> page
<header>
    <a href['/']> [site_name]
    (user is not null)
        <span> signed in as [user.name]
<page>

Conditional layouts

Swap the shell with a guard

Guards work inside main.rat too. Render a different layout based on the route, the user, or the build mode. The matched page still inlines at the page slot wherever you place it.

# main.rat
> page
(route == '/login')
    <main class['centered']>
        <page>
(else)
    <header>
        <nav> ...
    <main>
        <page>

See also Routing · State tiers · Guards and loops