Skip to main content
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:
src/data/pages/home.json — hero section
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.
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.
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 for the pointer syntax.
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 below.

Available sections

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

header

Site-wide navigation bar with logo text, optional announcement strip, and a menu array.

footer

Site-wide footer with brand text, tagline, email, copyright, and a menu array.

hero

Full-width landing hero with title, optional highlight span, subtitle, up to two CTAs, and an optional image.

page-hero

Compact interior-page header with label, title, and description. No image or CTA slots.

posts-list

Grid or bento layout of post cards driven by the posts collection. Supports a limit field for truncation.

tags-list

Card grid of all tags driven by the tags collection. Each card links to its tag detail page.

post-detail

Full essay view with title, author, date, reading time, image, and rendered body text.

related-tags

Shows the tags attached to a post by resolving the post’s tags relation against the tags collection.

tag-detail

Tag header card showing the tag’s name, description, and accent color.

tag-posts

Filters the full posts collection at render time to show only posts that carry the current tag.

content-block

Rich text block for long-form prose pages like About and Contact.

stats-band

Horizontal band of icon-backed statistics. Each stat has an icon, value, and label.

cta-banner

Full-width call-to-action banner with a title, optional description, and up to two CTA buttons.

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.
Section settings example
The common settings fields are: 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:
    src/lib/ComponentRegistry.tsx
  3. Register the schema — open src/lib/schemas.ts and add your schema to SECTION_SCHEMAS:
    src/lib/schemas.ts
  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.
See the hero section reference 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.