Route layouts
A layout is a shared shell template that wraps a page. It is the AkurAI-Framework take on the nested-layout idea from SvelteKit and Next.js: write the surrounding chrome once, then point any number of routes at it.
Layouts are opt-in and fully backward compatible — a route without a layout renders exactly as it did before.
Declaring a layout
Add an optional "layout" field to a route in backend/routes.json. Its value is the file stem of a template in frontend/ (a *.html file), just like template:
{
"routes": [
{ "path": "/", "template": "index" },
{
"path": "/welcome",
"template": "welcome",
"layout": "marketing"
}
]
}
Existing fields keep working untouched. You can combine layout with the SEO title/description fields on the same route.
How composition works
When a matched route declares a layout, the server renders in two passes:
- The page
templateis rendered with the usual context (routeparams, any
per-route meta_*, and the project-wide page.json context).
- That rendered HTML is injected back into the same context under the key
content, and the layout template is rendered. The layout pulls the page output in with the raw-output tag {{{ content }}}.
This is the same one-pass-into-a-shell composition the docs pages already use — now available declaratively to any route.
A route with no layout renders in a single pass, exactly as before.
Writing a layout template
A layout owns the document shell (head, header, footer) and drops the page where {{{ content }}} appears:
{% include "header" %}
<main class="container">
<div class="marketing-shell">
{{{ content }}}
</div>
</main>
{% include "footer" %}
The matching page template then holds only its own content — no <head>, header, or footer, since the layout supplies those:
<section class="page-head">
<h1>Welcome to the marketing shell</h1>
<p class="lede">This fragment is wrapped by the shared layout.</p>
</section>
The page fragment and the layout both see the full render context, so either can read {{ params.* }}, {{ title }}, nav, and anything else from page.json.
Live demo
The site itself ships a working example: the /welcome route uses the marketing layout to wrap the content-only welcome page template.