Lesson 02 of 10

Layouts & Page Structure

Layouts are the foundation of every OrbLayout site. Define your HTML boilerplate once, then reuse it across every page โ€” automatically.

The Problem Layouts Solve

Without layouts, every HTML page repeats the same boilerplate:

Without OrbLayout html
<!-- You copy-paste this into EVERY page -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Site</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>...</header>  <!-- Same on every page -->
  <nav>...</nav>        <!-- Same on every page -->

  <!-- Only THIS part changes -->
  <main>
    <h1>Hello World</h1>
  </main>

  <footer>...</footer>  <!-- Same on every page -->
</body>
</html>

With 10 pages, that's 10 copies of the same header, nav, footer, and meta tags. Change the nav? Edit 10 files. ๐Ÿ˜ฉ

Layouts solve this. Write the shell once. Each page only provides its unique content.

Creating a Layout

A layout file lives in the layouts/ folder and uses the .layout extension. It's just HTML with a special placeholder: {{ content }}.

layouts/main.layout .layout
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{ title }}</title>
</head>
<body>
  <header>
    <h1>My Website</h1>
    <nav>
      <a href="/">Home</a>
      <a href="/about">About</a>
    </nav>
  </header>

  <main>
    {{ content }}
  </main>

  <footer>
    <p>© 2026 My Website</p>
  </footer>
</body>
</html>
๐Ÿ“

{{ content }} is the magic placeholder. Whatever a page puts inside its <content> block will replace this marker.

Using a Layout in Pages

In your .orb page, reference the layout with <layout src="..."> and put your page content inside <content>:

pages/index.orb .orb
<layout src="main.layout">
  <content>
    <h2>Welcome Home!</h2>
    <p>This is the home page.</p>
  </content>
</layout>
pages/about.orb .orb
<layout src="main.layout">
  <content>
    <h2>About Us</h2>
    <p>We build cool stuff.</p>
  </content>
</layout>

Both pages share the same layout. The only difference is what's inside <content>.

My Website

Welcome Home!

This is the home page.

© 2026 My Website

Layout Variables

Notice the {{ title }} in the layout? You can populate it using a data block in your page:

pages/index.orb .orb
<script data>
({
  title: "Home โ€” My Website"
})
</script>

<layout src="main.layout">
  <content>
    <h2>Welcome Home!</h2>
  </content>
</layout>

The title from the data block flows into the layout's <title>{{ title }}</title>. This is how each page gets a unique browser tab title.

๐Ÿ’ก

Data blocks are covered in depth in Lesson 4. For now, just know they pass data to the layout.

Named Slots

Sometimes a layout needs multiple content areas, not just one. Named slots make this possible.

layouts/docs.layout .layout
<!DOCTYPE html>
<html>
<body>
  <div class="layout">
    <aside class="sidebar">
      {{ sidebar }}
    </aside>
    <main class="content">
      {{ content }}
    </main>
  </div>
</body>
</html>
pages/docs.orb .orb
<layout src="docs.layout">
  <content>
    <h1>Documentation</h1>
    <p>Welcome to the docs.</p>
  </content>

  <slot:sidebar>
    <nav>
      <a href="#intro">Introduction</a>
      <a href="#api">API Reference</a>
      <a href="#faq">FAQ</a>
    </nav>
  </slot:sidebar>
</layout>

<slot:sidebar> fills the {{ sidebar }} placeholder. <content> fills {{ content }}. You can create as many named slots as you need.

๐Ÿ“

Rules: The slot name after <slot: must match the {{ variableName }} in the layout. The closing tag must match too: </slot:sidebar>.

Multiple Layouts

You're not limited to one layout! Create different layouts for different page types:

File Structure structure
layouts/
โ”œโ”€โ”€ main.layout        โ† Standard pages (home, about)
โ”œโ”€โ”€ docs.layout        โ† Documentation (sidebar + content)
โ”œโ”€โ”€ blog.layout        โ† Blog posts (author, date, content)
โ””โ”€โ”€ landing.layout     โ† Landing pages (full-width, no nav)

Each page chooses its layout via src="...":

pages/index.orb .orb
<layout src="main.layout">
  ...
</layout>
pages/blog/post.orb .orb
<layout src="blog.layout">
  ...
</layout>

โœ… Lesson 2 Checkpoint

You should now understand:

  1. Layouts define the page shell with {{ content }} as a placeholder
  2. Pages reference layouts with <layout src="...">
  3. Page content goes inside <content>...</content>
  4. Named slots (<slot:name>) create multiple content areas
  5. Variables like {{ title }} in layouts get filled by page data blocks
  6. You can create multiple layouts for different page types