Rat docs

Dynamic routes

Wrap a path segment in square brackets to make it dynamic. pages/blog/[slug].rat matches /blog/anything and exposes the captured value as args.slug (or just slug at the top level) in the page's scope.

One dynamic segment

pages/blog/.rat → /blog/...

The bracketed filename becomes the capture name. args.slug is the captured string for that request — empty captures (e.g. /blog/) miss this route and fall through to a 404.

# pages/blog/[slug].rat
> server
title: 'Blog post'

> page
<h1> [args.slug]
<p> URL was /blog/[args.slug]

Mix static and dynamic segments

Folders may interleave freely

Bracket-folders can sit anywhere in the path. Static segments must match literally; bracket segments capture and bind. Multiple captures stack into args by name.

pages/users/[id]/posts/[post_id].rat
# matches /users/42/posts/hello
# args.id == '42'
# args.post_id == 'hello'

Read the value directly

Top-level slug bindings

Each capture is also bound at the top level of the scope under its name. [slug] and [args.slug] resolve to the same value — use whichever reads better at the call site.

# pages/blog/[slug].rat
> server
post: main_db.post.get_by_slug(slug)

> page
<h1> [post.title]

Next: Main shell — wrapping every page with a shared layout from main.rat.