> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olonjs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sections in OlonJS: composable page building blocks

> Learn how OlonJS sections work: typed React components backed by Zod schemas, assembled from JSON data payloads and display settings to compose full pages.

Sections are the building blocks of every OlonJS page. Each section is a typed React component backed by a Zod schema that validates its data payload. You compose pages by assembling sections in a JSON array — changing the order, adding new sections, or swapping types is a data change, not a code change. The engine validates each section's data against its schema at build time and in the Studio editor as you type.

## Section anatomy

A section object in a page bundle has four fields. Here is the hero section from the home page:

```json title="src/data/pages/home.json — hero section" theme={null}
{
  "id": "home-hero",
  "type": "hero",
  "data": {
    "label": "An OlonJS collections demo",
    "title": "Notes on the",
    "titleHighlight": "craft of software",
    "subtitle": "Essays on design, engineering and process — published as a living demo of cross-collection relations: every post belongs to many tags, and every tag knows its posts without storing them twice.",
    "primaryCta": {
      "id": "home-hero-cta-1",
      "label": "Read the posts",
      "href": "/posts",
      "variant": "primary"
    },
    "secondaryCta": {
      "id": "home-hero-cta-2",
      "label": "Browse topics",
      "href": "/tags",
      "variant": "secondary"
    },
    "image": {
      "url": "https://images.unsplash.com/photo-1456735190827-d1262f71b8a3?w=2000&q=80",
      "alt": "Fountain pen nib in sharp close-up over paper"
    }
  },
  "settings": {
    "paddingTop": "xl",
    "paddingBottom": "none"
  }
}
```

<ParamField path="id" type="string" required>
  A unique identifier for this section within the page. The catch-all page uses it as the React `key` prop, and Studio uses it to target the correct section in the Inspector. Convention: `<page-name>-<section-purpose>`, for example `home-hero`.
</ParamField>

<ParamField path="type" type="string" required>
  The section component to render. Must exactly match one of the keys registered in `ComponentRegistry` — for example `hero`, `posts-list`, or `cta-banner`. The engine looks up the component by this key and passes the resolved `data` and `settings` as props.
</ParamField>

<ParamField path="data" type="object" required>
  The content payload for the section. Shape is validated by the section's Zod schema. Fields can be plain values or `$ref` pointers that resolve to collection data. See [Collections](/concepts/collections#using-collections-in-sections) for the pointer syntax.
</ParamField>

<ParamField path="settings" type="object">
  Layout and display options such as spacing and visibility flags. All settings fields are optional. An empty object `{}` is valid and applies all defaults. See [Section settings](#section-settings) below.
</ParamField>

## Available sections

OlonJS ships with 13 built-in section types. Every section has its own schema reference page.

<CardGroup cols={2}>
  <Card title="header" icon="rectangle-wide" href="/reference/sections/header">
    Site-wide navigation bar with logo text, optional announcement strip, and a menu array.
  </Card>

  <Card title="footer" icon="rectangle-wide" href="/reference/sections/footer">
    Site-wide footer with brand text, tagline, email, copyright, and a menu array.
  </Card>

  <Card title="hero" icon="star" href="/reference/sections/hero">
    Full-width landing hero with title, optional highlight span, subtitle, up to two CTAs, and an optional image.
  </Card>

  <Card title="page-hero" icon="heading" href="/reference/sections/page-hero">
    Compact interior-page header with label, title, and description. No image or CTA slots.
  </Card>

  <Card title="posts-list" icon="list" href="/reference/sections/posts-list">
    Grid or bento layout of post cards driven by the posts collection. Supports a `limit` field for truncation.
  </Card>

  <Card title="tags-list" icon="tags" href="/reference/sections/tags-list">
    Card grid of all tags driven by the tags collection. Each card links to its tag detail page.
  </Card>

  <Card title="post-detail" icon="file-lines" href="/reference/sections/post-detail">
    Full essay view with title, author, date, reading time, image, and rendered body text.
  </Card>

  <Card title="related-tags" icon="link" href="/reference/sections/related-tags">
    Shows the tags attached to a post by resolving the post's `tags` relation against the tags collection.
  </Card>

  <Card title="tag-detail" icon="tag" href="/reference/sections/tag-detail">
    Tag header card showing the tag's name, description, and accent color.
  </Card>

  <Card title="tag-posts" icon="filter" href="/reference/sections/tag-posts">
    Filters the full posts collection at render time to show only posts that carry the current tag.
  </Card>

  <Card title="content-block" icon="align-left" href="/reference/sections/content-block">
    Rich text block for long-form prose pages like About and Contact.
  </Card>

  <Card title="stats-band" icon="chart-bar" href="/reference/sections/stats-band">
    Horizontal band of icon-backed statistics. Each stat has an icon, value, and label.
  </Card>

  <Card title="cta-banner" icon="bullhorn" href="/reference/sections/cta-banner">
    Full-width call-to-action banner with a title, optional description, and up to two CTA buttons.
  </Card>
</CardGroup>

## Section settings

Every section accepts a `settings` object that controls layout and display behaviour. All fields are optional — omitting `settings` entirely or passing `{}` applies the defaults.

```json title="Section settings example" theme={null}
{
  "settings": {
    "paddingTop": "xl",
    "paddingBottom": "none"
  }
}
```

The common settings fields are:

| Field | Type | Values | Description |
| - | - | - | - |
| `paddingTop` | `string` | `none` \| `sm` \| `md` \| `lg` \| `xl` \| `2xl` | Vertical spacing above the section. Defaults to `md`. |
| `paddingBottom` | `string` | `none` \| `sm` \| `md` \| `lg` \| `xl` \| `2xl` | Vertical spacing below the section. Defaults to `md`. |
| `sticky` | `boolean` | `true` \| `false` | Pins the `header` section to the top of the viewport on scroll. |
| `showLogo` | `boolean` | `true` \| `false` | Controls logo visibility in the `footer` section. |

Settings that are not relevant to a given section type are silently ignored, so it is safe to include them when copying section objects between pages.

## Registering a custom section

To add a section that is not in the built-in list, follow these steps:

1. **Create the component folder** — add a directory under `src/components/my-section/` with four files:
   * `schema.ts` — export `MySchema` extending `BaseSectionData` with your Zod fields
   * `types.ts` — export `MyData` and `MySettings` types derived from the schema
   * `View.tsx` — the React component that renders the section
   * `index.ts` — re-exports all of the above

2. **Register in ComponentRegistry** — open `src/lib/ComponentRegistry.tsx` and add your component:

   ```typescript title="src/lib/ComponentRegistry.tsx" theme={null}
   import { MySection } from '@/components/my-section';

   export const ComponentRegistry = {
     // ...existing entries...
     'my-section': MySection,
   };
   ```

3. **Register the schema** — open `src/lib/schemas.ts` and add your schema to `SECTION_SCHEMAS`:

   ```typescript title="src/lib/schemas.ts" theme={null}
   import { MySchema } from '@/components/my-section';

   export const SECTION_SCHEMAS = {
     // ...existing entries...
     'my-section': MySchema,
   };
   ```

4. **Add type augmentation** — open `src/types.ts` and extend the `SectionDataRegistry` and `SectionSettingsRegistry` module augmentation blocks with your new data and settings types.

Once registered, you can use `"type": "my-section"` in any page bundle, and Studio's section picker will include your new type.

<Tip>
  See the [hero section reference](/reference/sections/hero) for a complete worked example of a section schema, types file, and component — it is the simplest full-featured section in the codebase and a good template for custom sections.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.