Components are the heart of OrbLayout. Build reusable UI blocks, customize them with props, nest them inside each other, and add component-scoped styles.
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.
<!-- 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>
<!-- 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" />
Components are .orb files in the components/ folder. The content is just HTML with {{ prop }} placeholders.
<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.
<section class="hero">
<h1>{{ heading }}</h1>
<p>{{ subheading }}</p>
<a href="{{ link }}" class="btn">{{ buttonText }}</a>
</section>
<span class="badge" style="background: {{ color }}">
{{ text }}
</span>
Reference a component with the <use component="name" /> tag. It must be self-closing (/>).
<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.
When a component has many props, spread them across multiple lines for readability:
<use component="hero"
heading="Build the Future"
subheading="A modern static site builder"
link="/get-started"
buttonText="Start Now"
/>
Props are attributes on the <use> tag that get injected into the component's {{ }} placeholders.
<div class="alert alert-{{ type }}">
<strong>{{ title }}</strong>
<p>{{ message }}</p>
</div>
<use component="alert"
type="success"
title="Saved!"
message="Changes saved."
/>
Result:
Changes saved.
Props can reference page-level data variables using {{ }} syntax:
<script data>
({
siteName: "My Cool Site"
})
</script>
<use component="header"
title="{{ siteName }}" />
Components can use other components! OrbLayout resolves them recursively.
<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.
Components can include <style> blocks. The CSS gets extracted and injected into the page's <head>.
<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.
Import components with custom names using the <import> tag:
<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.
title, description, imageUrl — not t, d, img.badge.orb, avatar.orb, card.orb — then combine them in pages.You should now be able to:
components/<use component="name" />title="Hello"<style> blocks to components<import component="card" as="Card" />