Lesson 03 of 10

Components & Props

Components are the heart of OrbLayout. Build reusable UI blocks, customize them with props, nest them inside each other, and add component-scoped styles.

What Are Components?

A component is a reusable HTML block that you define once and use anywhere. Think of it like a rubber stamp — you design the stamp, then stamp it wherever you need it.

Without Components html
<!-- Copy-paste everywhere -->
<div class="card">
  <h3>Feature A</h3>
  <p>Description A</p>
</div>
<div class="card">
  <h3>Feature B</h3>
  <p>Description B</p>
</div>
<div class="card">
  <h3>Feature C</h3>
  <p>Description C</p>
</div>
With Components .orb
<!-- Write once, use anywhere -->
<use component="card"
  title="Feature A"
  description="Description A" />

<use component="card"
  title="Feature B"
  description="Description B" />

<use component="card"
  title="Feature C"
  description="Description C" />

Creating a Component

Components are .orb files in the components/ folder. The content is just HTML with {{ prop }} placeholders.

components/card.orb .orb
<div class="card">
  <h3>{{ title }}</h3>
  <p>{{ description }}</p>
</div>

{{ title }} and {{ description }} are props — they'll be filled in when the component is used.

More examples

components/hero.orb .orb
<section class="hero">
  <h1>{{ heading }}</h1>
  <p>{{ subheading }}</p>
  <a href="{{ link }}" class="btn">{{ buttonText }}</a>
</section>
components/badge.orb .orb
<span class="badge" style="background: {{ color }}">
  {{ text }}
</span>

Using Components

Reference a component with the <use component="name" /> tag. It must be self-closing (/>).

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

    <use component="hero"
      heading="Welcome!"
      subheading="Build amazing static sites"
      link="/features"
      buttonText="Learn More" />

    <use component="card"
      title="Fast"
      description="Zero runtime JS" />

    <use component="card"
      title="Simple"
      description="Just HTML" />

  </content>
</layout>
⚠️

Important: The component tag MUST be self-closing with />. Writing <use component="card"></use> will not work.

Multi-line attributes

When a component has many props, spread them across multiple lines for readability:

Multi-line Props .orb
<use component="hero"
  heading="Build the Future"
  subheading="A modern static site builder"
  link="/get-started"
  buttonText="Start Now"
/>

Props — Passing Data

Props are attributes on the <use> tag that get injected into the component's {{ }} placeholders.

Component Definition components/alert.orb
<div class="alert alert-{{ type }}">
  <strong>{{ title }}</strong>
  <p>{{ message }}</p>
</div>
Usage with Props .orb
<use component="alert"
  type="success"
  title="Saved!"
  message="Changes saved."
/>

Result:

Saved!

Changes saved.

Props can contain variables

Props can reference page-level data variables using {{ }} syntax:

Dynamic Props .orb
<script data>
({
  siteName: "My Cool Site"
})
</script>

<use component="header"
  title="{{ siteName }}" />

Nested Components

Components can use other components! OrbLayout resolves them recursively.

components/header.orb .orb
<header>
  <h1>{{ title }}</h1>
  <!-- Using badge INSIDE header -->
  <use component="badge" text="v1.2" color="#6c5ce7" />
</header>

When the page is compiled, OrbLayout first resolves the header component, then finds the badge inside it and resolves that too. This works to any nesting depth.

💡

Circular references are detected. If component A uses component B, and B uses A, OrbLayout will warn you to prevent infinite loops.

Component Styles

Components can include <style> blocks. The CSS gets extracted and injected into the page's <head>.

components/card.orb .orb
<style>
.card {
  background: #fff;
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  transition: transform 0.2s;
}
.card:hover {
  transform: translateY(-4px);
}
</style>

<div class="card">
  <h3>{{ title }}</h3>
  <p>{{ description }}</p>
</div>

If you use this card 10 times on a page, the <style> block is only included once — OrbLayout deduplicates styles automatically.

Imports & Aliases

Import components with custom names using the <import> tag:

Using Imports .orb
<import component="card" as="Card" />
<import component="badge" as="Badge" />

<!-- Now use the alias -->
<Card title="Hello" description="World" />
<Badge text="New" color="#6c5ce7" />

This gives you a React/Vue-like syntax where components start with a capital letter. Both <use component="card" /> and <Card /> produce the same output.

Best Practices

  • One responsibility per component. A card is a card, not a card-with-nav-and-footer.
  • Name props clearly. Use title, description, imageUrl — not t, d, img.
  • Compose from small pieces. Build badge.orb, avatar.orb, card.orb — then combine them in pages.
  • Use styles in components. Keep CSS next to the HTML it styles.
  • Keep components in layouts too. Headers and footers work great as components inside layouts.

✅ Lesson 3 Checkpoint

You should now be able to:

  1. Create a component file in components/
  2. Use it with <use component="name" />
  3. Pass data via props: title="Hello"
  4. Nest components inside other components
  5. Add <style> blocks to components
  6. Import with aliases: <import component="card" as="Card" />