Skip to main content
A layout is the shell every page shares: the doctype, the <head>, the nav and the footer. The page supplies only its own content, which lands at the layout’s <slot />.

Declaring a layout

Layouts live in layouts/, where they are checked but never emitted as a page.
layouts/base.slurp
Enter it from a page with the {layout} block:
index.slurp
The page’s children replace <slot />, and the {head} block replaces <slot name="head" />.
dist/index.html
The output is minified, and the canonical link landed in the head rather than next to the <h1>.

The element form has no head slot

There is also an element form, <layout src="@layouts/base">. It fills the default slot the same way, and that is all it does.
The element form builds its node with no head slot. A {head} block inside it is treated as an ordinary child and renders inline in the body, usually inside <main>, where those tags do nothing.
Use {layout "..."} whenever the page contributes anything to the head. The failure is silent.
The src must be a quoted string. <layout src={expr}> reads as empty, the layout is never entered, and the page renders bare.

The head block

A {head} must be a direct child of the {layout} block. The extraction scans the block’s top-level children only.
That nested block renders inline in the body instead. Put the condition inside the head block, or in the layout. A {head} inside a component is not extracted either, for the same reason: only the layout’s own children are scanned. If a page writes two {head} blocks, the last one wins and the first is discarded with no diagnostic.

Title and description ownership

Both the layout and the page can write to <head>. In the example theme the layout owns the title and description, driven by an seo value in the render context, and the head slot carries additional tags such as a canonical link or structured data.
layouts/base.slurp
Guarding both means a page that supplies no seo gets neither an empty <title> nor an empty description, and is free to emit its own. Without the guard a page that emits a title in its head block produces two.

A layout takes no props

A layout renders against the page globals and nothing else. Props are not passed to it by either form, and a props block’s defaults are NOT applied.
layouts/tiny.slurp
Both render heading=[]. The attribute is ignored and the default never applies.
So a props block in a layout is documentation for the reader. To vary a layout per page, put the value in the render context and read it as a global. That is what seo does above.

Named slots do not exist

Only default and head are ever filled. Any other name renders as a literal <slot> element carrying its fallback content.
layouts/base.slurp
index.slurp
dist/index.html
You get both copies, in the wrong place, with no diagnostic. The child went to the default slot like every other child, and the named slot rendered its fallback. Anything that would have been a second slot becomes a global the layout reads, or its own component that the page places in the default slot.

Other slot behaviour

Slot content is cloned per slot. A layout with two <slot /> elements renders the page body twice. That is occasionally intended and more often a typo.
{layout "@layouts/noslot"}<p>lost</p>{/layout} renders the layout and nothing else. The page content is discarded silently.

Nesting

A layout can enter another layout, which is how a section shell wraps the site shell.
layouts/docs.slurp
A page entering @layouts/docs gets both. A layout that enters itself is stopped by a cycle guard rather than an error. Imports are per file. A layout that uses a component imports it in its own frontmatter; it does not inherit the page’s using lines.
layouts/base.slurp

When a layout does not resolve

Like a component, an unresolved layout does not fail the build and is not reported by validate --warnings. The page content survives, wrapped in HTML comments that the minifier then strips, and a literal <slot></slot> is left in the output.
A page that suddenly has no chrome and a stray <slot> in it is a misspelled layout path.

Layout versus component

Both are .slurp files that other files include, and both are checked without being emitted. The difference is what they can take. Use a layout when the file wraps a whole page and needs to reach the head. Use a component everywhere else, including for regions inside a layout: a component can be parameterised and a layout cannot.

Next

Components

Props, scope, slots, and imports.

Pages and routing

File-based routing, page data, and output paths.

Sections and blocks

Schema declarations, blocks, and the merge.

Common mistakes

The silent failures, collected in one place.