Skip to content
Browse the guides

For developers

Connect settings to Content Lists.

Owners connect sections to Content Lists in the editor. Declare what your component can show, then render the values Mirin hands it when the page renders.

On this page

Two ways to connect

Owners connect components to Content Lists in the editor. A connection is saved on the page and resolved when the page renders, so your component receives plain values, never the connection.

One setting, one entry

A text setting shows one field of one entry, such as the title of a class.

  • The page saves a __binding object in place of the text.
  • When the page renders, Mirin swaps it for that field’s value.

One setting, a whole list

A content_list setting shows many entries, sorted and limited the way the owner chooses.

  • The page saves a __contentListBinding object.
  • When the page renders, Mirin swaps it for the list’s entries.

Connect a text setting to an entry

Every string, text, textarea and richtext setting shows Connect content list under its field. Nothing extra goes in the schema.

Class Spotlight

Class spotlight

This week’s class

A short note about the class we are featuring this week.

Book this class
Two people doing lunges on reformers in a bright studio with a window over a harbor.
{  "heading": "This week’s class",  "intro": "A short note about the class we are featuring this week.",  "photo": {    "url": "/images/home-next/salt-stone-pilates.webp",    "alt": "Two people doing lunges on reformers in a bright studio with a window over a harbor."  }}
Class Spotlight on the sample studio website. Choose Connect content list, pick the Classes list, an entry and a field, then Apply. The field becomes a chip, and the code panel shows what the page saves and what your component receives.
  1. Choose Connect content list under the field.
  2. In Connect to a record, keep Pick an entry, then choose the List, the Record and the Field.
  3. Choose Apply. The field shows the connection with Unbind beside it, and Change content connection underneath. Unbind puts the default back.

Which fields a setting accepts

A plain text setting
Accepts text, long text, number, true or false, date, URL, email and slug fields.
A textarea or richtext setting
Accepts text, long text and rich text fields.

Other fields stay in the list, disabled and marked incompatible. Use this page’s entry works on dynamic pages, where each page shows one entry of a list.

Connect a dynamic page automatically

On a dynamic page, adding a section can connect it to the page’s entry straight away. Mark the settings that describe the entry with supportsBinding: true, and leave layout and button settings unmarked.

InstructorProfile/schema.json
{
  "type": "instructor_profile",
  "displayName": "Instructor Profile",
  "category": "content",
  "description": "One instructor's photo, name, role and short bio.",
  "props": {
    "name": { "type": "string", "displayName": "Name", "supportsBinding": true, "default": "Instructor name" },
    "photo": { "type": "image", "displayName": "Photo", "supportsBinding": true, "default": { "url": "", "alt": "" } },
    "role": { "type": "string", "displayName": "Role", "supportsBinding": true, "default": "Instructor" },
    "bio": { "type": "textarea", "displayName": "Short bio", "supportsBinding": true, "default": "" },
    "buttonText": { "type": "string", "displayName": "Button text", "default": "Book with me" }
  }
}
supportsBinding:

Add section

A dynamic page for the Instructors list, previewing Maya Brooks.

Instructor Profile

Content · v1.0.0

These fields can be edited independently on each page after you add this section.

Namestring
Photoimage
Rolestring
Short biotextarea
Button textstring
Two people doing lunges on reformers in a bright studio with a window over a harbor.

Instructor

Instructor name

A few lines about how this instructor teaches.

Book with me
{  "type": "instructor_profile",  "displayName": "Instructor Profile",  "props": {    "name": {      "type": "string",      "displayName": "Name",      "supportsBinding": true,      "default": "Instructor name"    },    "photo": {      "type": "image",      "displayName": "Photo",      "supportsBinding": true,      "default": {        "url": "/images/home-next/salt-stone-pilates.webp",        "alt": "Two people doing lunges on reformers in a bright studio with a window over a harbor."      }    },    "role": {      "type": "string",      "displayName": "Role",      "supportsBinding": true,      "default": "Instructor"    },    "bio": {      "type": "textarea",      "displayName": "Short bio",      "default": "A few lines about how this instructor teaches."    },    "buttonText": {      "type": "string",      "displayName": "Button text",      "supportsBinding": true,      "default": "Book with me"    }  }}
A dynamic page for the sample Instructors list. Change which settings are marked, then choose Add section. Marked settings that match a field connect to the page’s entry, and the message names them. Start over to try other marks.
What connects
A marked setting whose key or displayName matches a field’s slug or name. Case, spaces and punctuation are ignored, and a near miss stays unconnected.
One setting per field
Each field connects to the first matching setting only.
What the owner sees
A message such as Connected 3 fields, with the names of the fields that now come from the entry on this page.
Any setting type
Marked image, link, number and color settings connect too. What each one receives is under What a connected setting receives.

Show a whole list

Declare a content_list setting with editable: true. The owner sees Connect a Content List, picks a list in the drawer, and checks how its fields fill your slots.

ClassSchedule/schema.json
{
  "type": "class_schedule",
  "displayName": "Class Schedule",
  "category": "content",
  "description": "Upcoming classes from a connected Content List.",
  "props": {
    "heading": { "type": "string", "displayName": "Heading", "default": "Upcoming classes" },
    "classes": {
      "type": "content_list",
      "displayName": "Classes",
      "editable": true,
      "itemShape": {
        "title": { "type": "string", "required": true },
        "startsOn": { "type": "date" },
        "photo": { "type": "image" },
        "instructor": { "type": "string" }
      },
      "defaultSort": "starts:asc",
      "defaultLimit": 3
    }
  }
}

Class Schedule

Connected list

Classes

Used on this page only

Display options

items

These display options apply to this section only.

Class schedule

Upcoming classes

  • A smiling woman with wavy brown hair and a cream cardigan, seated in a pink armchair.
    Stretch and RestoreSat, Oct 3 · Nora Ellis
  • Two people doing lunges on reformers in a bright studio with a window over a harbor.
    Reformer FlowTue, Oct 6 · Maya Brooks
  • A smiling woman with wavy brown hair and a cream cardigan, seated in a pink armchair.
    Core and BalanceThu, Oct 8 · Nora Ellis
{  "heading": "Upcoming classes",  "classes": {    "__contentListBinding": {      "collectionSlug": "classes",      "collectionId": "c7k2m9x4q1",      "fieldMap": {        "title": "title",        "startsOn": "starts",        "photo": "photo",        "instructor": "instructor"      },      "limit": 3,      "sort": "starts:asc"    }  }}
Class Schedule on the sample studio website, connected to the Classes list. Change Sort by and Show up to, choose Change to open the drawer and its Field map, or Disconnect and connect again. The preview and the code panel follow every change.
editable
true shows Connect a Content List, so the owner chooses the list. Without it the owner cannot choose one.
itemShape
The slots each entry fills, each with a type and an optional required. The Field map suggests a field for every slot, first by a matching slug or name, then by the first field that fits.
defaultSort
The sort a new connection starts with, such as starts:asc or published_at:desc.
defaultLimit
How many entries a new connection shows.

Without itemShape, the drawer says the component does not declare an item shape, so no field map is needed. Entries then carry only their own field slugs.

Render the entries

When the page renders, the setting arrives as an array. Each entry has id, slug, primaryValue, publishedAt and data. data holds the entry’s fields by slug, plus each slot name from the field map.

ClassSchedule/index.tsx
type Photo = { url?: string; alt?: string };

type ClassEntry = {
  id: string;
  slug: string | null;
  primaryValue: string | null;
  publishedAt: string | null;
  data: { title?: string; startsOn?: string; photo?: Photo; instructor?: string };
};

type ClassScheduleProps = {
  heading?: string;
  classes?: ClassEntry[];
};

export default function ClassSchedule({ heading = '', classes }: ClassScheduleProps) {
  const entries = Array.isArray(classes) ? classes : [];

  return (
    <section className="class-schedule">
      <h2>{heading}</h2>
      {entries.length === 0 ? (
        <p>No classes to show yet.</p>
      ) : (
        <ul>
          {entries.map((entry) => (
            <li key={entry.id}>
              {entry.data.photo?.url && <img src={entry.data.photo.url} alt={entry.data.photo.alt ?? ''} />}
              <strong>{entry.data.title}</strong>
              <span>{entry.data.startsOn} with {entry.data.instructor}</span>
            </li>
          ))}
        </ul>
      )}
    </section>
  );
}

Until an owner connects a list, the setting is not an array, so check it before you map over it. Only published entries reach the page.

Sort, limit and pages

Under Display options, Sort by and Show up to apply to this section only. Sort by offers the list’s text, long text, slug, number, date, email and URL fields in either direction. Use list default clears the sort.

<field slug>:asc or :desc
By that field of the connected list.
published_at:desc
Newest published first. Used when no sort is set.
created_at:asc or :desc
By when each entry was created.
updated_at:asc or :desc
By when each entry last changed.
primary_value:asc or :desc
By each entry’s primary value, such as its title.

There is no published_at:asc. A sort the list cannot use returns no entries, so a field slug in defaultSort only works with a list that has that field.

Pages on a long list

Without a limit, a page shows up to 50 entries. When a list has more entries than the limit, the published page adds Previous page and Next page links under the section, with a line such as Page 2 of 3. Each of those pages has its own address ending in ?page=2.

What a connected setting receives

Mirin converts the entry’s value to fit the setting’s type before your component renders.

string or text
The field as text. Numbers and true or false become text, and a rich text field becomes its plain text.
textarea or richtext
The field’s value, cleaned before your component receives it.
link or url
A full http, https, mailto or tel address, or a path starting with / or #. Anything else arrives as null.
image
An object with url and alt, from an image field only. Any other field arrives as null.
number
A number, from a number field or from text that reads as one. Anything else arrives as null.
boolean
true or false.
color
A hex, rgb, hsl or named color. Anything else arrives as null.

Handle null

A connection arrives as null when its entry is deleted or unpublished, when its field was removed, or when the value does not convert. Default parameter values do not replace null, so give each value a fallback.

InstructorProfile/index.tsx
type InstructorProfileProps = {
  name?: string | null;
  photo?: { url: string; alt: string } | null;
  role?: string | null;
};

export default function InstructorProfile({ name, photo, role }: InstructorProfileProps) {
  return (
    <section className="instructor-profile">
      {photo?.url && <img src={photo.url} alt={photo.alt} />}
      <h2>{name ?? 'Our instructor'}</h2>
      {role && <p>{role}</p>}
    </section>
  );
}

Content List fields in data

Inside a list entry, data keeps each field in its own shape.

text, longText, slug, url, email, select
Text.
number
A number.
boolean
true or false.
date
Calendar date text, such as 2026-10-06.
image
An object with assetId, alt, decorative and url.
richtext
A rich text document as JSON, not HTML.
color
Lowercase hex text, #rrggbb or #rrggbbaa.

Keep a date on its own day

Preserve the selected day when you format a date. Do not convert it to the visitor’s time zone. Compare event days in the venue’s time zone, keeping today’s events current through the end of that day.

Troubleshooting

What to check when a connection does not show what you expect.

Why does a connected setting render empty?
Its entry is unpublished or deleted, its field was removed, or the value does not fit the setting. The setting arrives as null.
Why does a list render no entries?
No list is connected yet, the list has no published entries, or the sort names a field the list does not have.
Why is a field disabled in the picker?
Its type does not fit the setting. A plain text setting cannot show an image or a select field.
Why does the drawer show no field map?
The setting has no itemShape. Add one so owners can match fields to your slots.
Why did a section not connect on a dynamic page?
The setting is not marked supportsBinding: true, or neither its key nor its displayName matches a field’s slug or name.