Wrap pages in shared HTML structure. Define it once, apply it everywhere.
A layout is an HTML file in your components/ directory. It uses <slot/> to mark where page content is injected.
<what>
props = "title"
defaults.title = "My Site"
</what>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>#title#</title>
<link rel="stylesheet" href="/static/what.css">
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<main>
<slot/>
</main>
<footer>
<p>© 2025 My Site</p>
</footer>
</body>
</html>
The <slot/> tag is replaced with the full content of the page that uses this layout.
Assign a layout to a page in its <what> block:
<what>
layout: "components/main-layout.html"
title: "About Us"
</what>
<h1>About Us</h1>
<p>We build things with HTML.</p>
The page content replaces the <slot/> in the layout. Props declared in the layout's <what> block (like title) receive values from the page's <what> block.
Instead of setting a layout on every page, define it once in an application.what file. Every page in that directory (and its subdirectories) inherits the layout automatically.
layout = "components/main-layout.html"
With this in place, every page under site/ uses main-layout.html without declaring it individually.
Subdirectories can override the parent layout:
layout = "components/admin-layout.html"
Now all pages in site/admin/ use the admin layout, while the rest of the site keeps the main layout.
Some pages need to render without any wrapping layout — API-like endpoints, standalone landing pages, or widget embeds. Use layout: none:
<what>
layout: none
</what>
<div class="widget">
<p>This renders without any layout.</p>
</div>
This overrides any inherited layout from application.what.
Layouts declare props in their <what> block. Pages pass values through their own <what> block:
<what>
props = "title, page, section"
defaults.title = "Docs"
defaults.section = ""
</what>
<!DOCTYPE html>
<html>
<head>
<title>#title# - Docs</title>
</head>
<body>
<if section>
<span class="badge">#section#</span>
</if>
<slot/>
</body>
</html>
<what>
title: "Variables & Filters"
page: templates
section: Templates
</what>
<h1>Variables & Filters</h1>
<p>Content goes here...</p>
The layout receives title, page, and section as props from the page. Props with defaults are optional.
Layout inheritance follows the directory tree. Each application.what applies to its directory and all children, unless overridden deeper in the tree.
site/
application.what <!-- layout = "components/main-layout.html" -->
index.html <!-- uses main-layout -->
about.html <!-- uses main-layout -->
blog/
application.what <!-- layout = "components/blog-layout.html" -->
index.html <!-- uses blog-layout -->
post.html <!-- uses blog-layout -->
admin/
application.what <!-- layout = "components/admin-layout.html" -->
dashboard.html <!-- uses admin-layout -->
settings.html <!-- uses admin-layout -->
The chain resolves from the page's directory upward. The first layout found wins. A page-level layout: directive always takes priority over application.what.
<slot/>.
Here's a typical project setup with a shared layout:
<what>
props = "title"
defaults.title = "wwwhat"
</what>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#title#</title>
<link rel="stylesheet" href="/static/what.css">
</head>
<body>
<header class="flex items-center justify-between p-4">
<a href="/">My App</a>
<nav class="flex gap-4">
<if user.authenticated>
<span>#user.full_name#</span>
<form method="post" action="/w-auth/logout">
<input type="hidden" name="_csrf" value="#_csrf#">
<button type="submit">Log out</button>
</form>
</if>
<else/>
<a href="/login">Log in</a>
</else>
</nav>
</header>
<main class="p-6">
<slot/>
</main>
<footer class="p-4 text-center text-sm text-muted">
<p>Built with wwwhat</p>
</footer>
</body>
</html>
layout = "components/site-layout.html"
<what>
title: "Home"
</what>
<h1>Welcome</h1>
<p>This page is wrapped in site-layout automatically.</p>