Block-Schema & Feldtypen

Alle Feldtypen, der defineBlock + fields Builder, Feldoptionen, Repeater und Select-Optionen.

20. März 2026

Alle Feldtypen

Definiere die editierbaren Props eines Blocks mit dem fields.*()-Builder innerhalb von defineBlock. Jeder Builder gibt eine Felddefinition zurück; der Schlüssel, den du ihm in props gibst, wird zum Content-Schlüssel.

BuilderBeschreibungWerttyp
fields.text()Einzeiliges Texteingabefeldstring
fields.textarea()Mehrzeilige Textareastring
fields.richText()WYSIWYG-Editor (Tiptap)string (HTML)
fields.markdown()Markdown-Editorstring (Markdown)
fields.number()Zahleneingabenumber
fields.date()Datumsauswahlstring (ISO date)
fields.datetime()Datums- & Zeitauswahlstring (ISO)
fields.boolean()Umschalterboolean
fields.color()Farbauswahlstring (hex)
fields.media()Bild-/Video-Uploadstring or string[]
fields.link()Interner/externer Linkstring
fields.url()URL-Eingabestring
fields.email()E-Mail-Eingabestring
fields.select()Dropdown (Einfachauswahl)string
fields.radio()Radio-Gruppe (Einfachauswahl)string
fields.multiselect()Mehrfachauswahlstring[]
fields.relation()Records eines Modells referenzierenrecord or record[]
fields.repeater()Array verschachtelter Feldgruppenobject[]
fields.table()Editierbares Tabellenraster{ columns, rows }
fields.json()Roher JSON-EditorJSON value
fields.form()Ein Cmssy-Formular wählenstring (form id)
fields.pageSelector()Seite(n) wählenPageRef[]

Die meisten Builder nehmen nur die Basisoptionen unten. fields.select(), fields.radio() und fields.multiselect() brauchen ein options-Array; fields.media() akzeptiert multiple; fields.relation() braucht ein model (den Slug des referenzierten Modells) und optional mode: "all", multiple, sort und limit. Eine Relation speichert Record-id(s); die Delivery-API löst sie zu vollständigen Records auf, bevor deine Komponente rendert.


Einen Block definieren

Ein Block wird mit defineBlock deklariert. Seine editierbaren Felder liegen unter props:

import { defineBlock, fields } from "@cmssy/react";
import Hero from "./Hero";

export const heroProps = {
  heading: fields.text({ label: "Heading", required: true, defaultValue: "Welcome" }),
  description: fields.textarea({ label: "Description" }),
};

export const heroBlock = defineBlock({
  type: "hero",
  label: "Hero",
  component: Hero,
  props: heroProps,
});

Exportiere das Props-Objekt separat und typisiere die Komponente daraus - BlockProps<typeof heroProps> - dann bleibt das Schema die einzige Stelle, an der ein Feld benannt wird, und die Werttypen aus der Tabelle oben werden zu den Typen, die deine Komponente sieht. Siehe Block-Entwicklung.


Feldoptionen

Jeder fields.*()-Builder akzeptiert dieselben Basisoptionen:

fields.text({
  label: "Heading",
  required: true,
  defaultValue: "Welcome",
  placeholder: "Enter text",
  helperText: "Main heading",
})

Verfügbare Schlüssel: label, required, defaultValue, placeholder, helperText. Select- und Repeater-Felder bringen noch ein paar weitere mit (siehe unten).


Select & Multiselect

Die Optionen sind ein einfaches Array aus Strings:

props: {
  layout: fields.select({
    label: "Layout",
    options: ["grid", "list", "carousel"],
    defaultValue: "grid",
  }),
  tags: fields.multiselect({
    label: "Tags",
    options: ["featured", "new"],
  }),
}

Repeater (Arrays)

Nutze itemSchema — eine Map aus verschachtelten fields.*() — um jede Zeile zu beschreiben:

props: {
  features: fields.repeater({
    label: "Features",
    maxItems: 6,
    itemSchema: {
      icon: fields.text({ label: "Icon Name", defaultValue: "Star" }),
      title: fields.text({ label: "Title", required: true }),
      description: fields.textarea({ label: "Description" }),
    },
  }),
}

In deiner Komponente:

export default function Features({ content }) {
  return (
    <div className="grid grid-cols-3 gap-6">
      {(content.features ?? []).map((f, i) => (
        <div key={i}><h3>{f.title}</h3><p>{f.description}</p></div>
      ))}
    </div>
  );
}

Repeater unterstützt außerdem itemLabel, addButtonLabel, minItems, maxItems und collapsible.