MADORIMADORI

Fieldsets

Fieldsets are reusable groups of fields that can be shared across blueprints. They serve two purposes: defining block types for Replicator fields and providing importable field groups to avoid duplicating field definitions across multiple blueprints.

When you define a fieldset, it becomes available as a Replicator block type and can be imported into any blueprint's tab or section.


Configuration Reference

File Location

Fieldsets live at resources/fieldsets/{handle}.yaml. The handle is used to reference the fieldset in Replicator sets arrays and blueprint import statements.

Fieldset Structure

Property Type Required Description
fields FieldConfig[] Yes Array of field definitions (same format as blueprint fields)
display string No Display name shown in the Replicator block picker. Auto-generated from handle if omitted
is_block boolean No When true, the fieldset is automatically available in blocks fields without explicit configuration

Field Configuration

Each field within a fieldset follows the same structure as blueprint fields:

fields:
  - handle: <field_handle>
    field:
      type: <field_type>
      display: <Human Label>
      required: <boolean>
      default: <default_value>
      validate: <string[]>
      options: <object>
      visibility: <object>

All field types and validation rules available in blueprints work identically in fieldsets.

API Endpoints

Method Endpoint Description
GET /api/fieldsets List all fieldsets
GET /api/fieldsets/{handle} Get a single fieldset
PUT /api/fieldsets/{handle} Create or update a fieldset
DELETE /api/fieldsets/{handle} Delete a fieldset

Usage Examples

Defining a Hero Block Fieldset

# resources/fieldsets/hero.yaml
is_block: true
fields:
  - handle: title
    field:
      type: text
      display: Title
      required: true
      validate:
        - required
        - max:120

  - handle: subtitle
    field:
      type: text
      display: Subtitle

  - handle: background_image
    field:
      type: asset
      display: Background Image
      options:
        max_files: 1

  - handle: button_text
    field:
      type: text
      display: Button Text

  - handle: button_link
    field:
      type: text
      display: Button Link
      validate:
        - url

Using Fieldsets as Blocks

Fieldsets with is_block: true are automatically available when using the blocks field type:

# In a blueprint — no sets configuration needed
- handle: page_content
  field:
    type: blocks
    display: Page Content

All fieldsets marked is_block: true become available block types. This is the simplest way to build page builders — just add a blocks field and create block fieldsets.

Using Fieldsets in Replicators

Reference fieldsets by handle in a Replicator field's sets option:

# In a blueprint
- handle: blocks
  field:
    type: replicator
    display: Page Blocks
    options:
      sets:
        - hero
        - features_grid
        - basic_cta
        - rich_text

Each block stored in entry data includes a _type field matching the fieldset handle:

blocks:
  - _type: hero
    title: Welcome to Madori
    subtitle: A flat-file CMS for Next.js
    button_text: Get Started
    button_link: /docs/getting-started
  - _type: basic_cta
    title: Ready to start?
    button_text: Sign Up
    button_link: /signup

Importing Fieldsets into Blueprints

Include a fieldset's fields directly in a blueprint using the import key:

tabs:
  main:
    display: Content
    fields:
      - handle: title
        field:
          type: text
          display: Title
          required: true

      - handle: body
        field:
          type: tiptap
          display: Body

  seo:
    display: SEO
    fields:
      - import: seo

This resolves the seo fieldset and injects its fields at that position in the tab.

Managing Fieldsets in the Control Panel

Navigate to Fieldsets in the CP sidebar to:

  1. View all defined fieldsets
  2. Create new fieldsets with the visual field editor
  3. Add, remove, and reorder fields within a fieldset
  4. Delete unused fieldsets

Common Patterns

Shared SEO Fields

Define SEO fields once and import them across all collection blueprints:

# resources/fieldsets/seo.yaml
fields:
  - handle: meta_title
    field:
      type: text
      display: Meta Title
      validate:
        - max:60
      options:
        placeholder: Override page title for search engines

  - handle: meta_description
    field:
      type: text
      display: Meta Description
      validate:
        - max:160
      options:
        placeholder: Brief description for search results

  - handle: og_image
    field:
      type: asset
      display: Social Share Image
      options:
        max_files: 1

Import into any blueprint:

sections:
  seo:
    display: SEO
    fields:
      - import: seo

Building a Block Library

Create a library of reusable page-building blocks:

resources/fieldsets/
├── hero.yaml              # Full-width hero with image
├── rich_text.yaml         # Simple text content block
├── features_grid.yaml     # Feature cards in a grid
├── basic_cta.yaml         # Call-to-action with button
├── testimonials.yaml      # Customer quotes
├── image_gallery.yaml     # Grid of images
├── video_embed.yaml       # Video player embed
└── pricing_table.yaml     # Pricing comparison

Then compose page builders by selecting which blocks are available:

# Landing pages get all blocks
- handle: blocks
  field:
    type: replicator
    options:
      sets:
        - hero
        - features_grid
        - basic_cta
        - testimonials
        - pricing_table

# Blog posts get simpler blocks
- handle: blocks
  field:
    type: replicator
    options:
      sets:
        - rich_text
        - image_gallery
        - video_embed
        - basic_cta

Nested Fieldsets

Fieldsets can import other fieldsets for composition. A CTA block might reuse a button fieldset:

# resources/fieldsets/button.yaml
fields:
  - handle: text
    field:
      type: text
      display: Button Text
      required: true

  - handle: url
    field:
      type: text
      display: Button URL
      validate:
        - url

  - handle: style
    field:
      type: select
      display: Button Style
      default: primary
      options:
        options:
          - primary
          - secondary
          - outline

Circular references between fieldsets are detected and produce an error at load time.

Consistent Block Naming

Use a consistent naming convention for fieldset handles:

  • Use snake_case for multi-word handles: features_grid, image_gallery
  • Group related blocks with prefixes: card_basic, card_featured, card_pricing
  • Keep handles short but descriptive — they appear in content YAML as _type values