Group

A group field is an organizational container that nests related fields into a single object. Groups don't store content themselves — they structure how fields are arranged in the editor and how data is nested in the API response. When a model has many fields, groups turn a flat list into a logical hierarchy that editors can navigate and developers can consume as nested JSON.

This page covers how groups work, column layouts for horizontal field arrangement, nesting groups inside groups, moving fields between groups without data loss, and how to decide between groups and other structural field types.


What Is a Group Field

A group field wraps a set of fields into a named, collapsible section in the editor. The fields inside a group are part of the same model — they aren't separate content that can be reused elsewhere. A group is purely organizational: it affects how editors see the fields and how the data is structured in the API response.

When you add a group field to a model, you configure:

A name and handle — The name is what editors see as the section heading in the editor. The handle determines the key name in the API response where the grouped fields are nested.

Fields — The fields that belong to the group. Any field type can be placed inside a group — text, images, references, collections, even other groups. The fields inside a group work exactly the same as fields at the top level of a model; grouping doesn't change their behavior or capabilities.

Column layout — The number of columns used to arrange fields horizontally within the group. This controls the visual layout of the editor, letting you place related fields side by side rather than stacking them vertically.

A group always produces exactly one instance. Unlike collections, which are repeatable, or dynamic block fields, which let editors add multiple sections, a group is a fixed container. Its fields always appear in the editor, and editors fill them in once. You can't add a second instance of a group or remove it from the editor — it's a permanent part of the model's structure.


Organizing Fields with Groups

Groups solve the problem of editor complexity. A page model with 15 fields presented as a flat list is harder to navigate than one where those fields are organized into three or four named sections. Groups give you that structure.

Common Grouping Patterns

SEO and metadata — Group meta title, meta description, Open Graph image, and canonical URL under an "SEO" group. Editors working on content can collapse this section until they need it, and developers receive the metadata as a clean nested object.

Hero or banner section — Group a heading, subheading, background image, and CTA button fields under a "Hero" group. This clusters visually related fields and produces a single hero object in the API.

Contact information — Group address, phone, email, and map location fields under a "Contact" group on a location page model. The editor sees one coherent section, and the API returns a contact object with all the details.

Social links — Group social media URLs (Twitter, LinkedIn, Instagram, YouTube) under a "Social" group on a site settings entry. Editors see them as a logical unit, and your template or frontend accesses them through settings.social.

Button or CTA fields — Group a button label, button URL, and button style dropdown under a "Button" group inside a block model. The block template accesses the button data as item.button.label, item.button.url, and item.button.style.

The pattern is consistent: whenever you have a set of fields that belong together conceptually, a group makes both the editing interface and the data structure cleaner.


Column Layouts

By default, fields inside a group stack vertically — one field per row, full width. Column layouts let you arrange fields horizontally, placing two, three, or four fields side by side in a single row.

When you configure a group, you select the number of columns. Fields within the group are then distributed across those columns in order, flowing left to right. This is an editor layout feature — it affects how fields are displayed in the editing interface, not how the data is structured in the API.

When to Use Columns

Columns work well when fields are short and logically paired. A "Name" group with first name and last name fields makes sense as two columns — editors see both fields on the same row, which reflects how they think about the data. A "Dimensions" group with width, height, and unit fields works as three columns.

Some practical examples:

Two columns — First name and last name. City and country. Start date and end date. Min price and max price. These are natural pairs where side-by-side layout improves scannability.

Three columns — Icon, title, and description for a compact feature entry. Width, height, and depth for product dimensions.

Four columns — Margin or padding values (top, right, bottom, left). Social media URLs where each is a short text field.

Avoid using columns for fields that need the full editor width, like rich text editors, markdown fields, or long text areas. These are better left at full width where editors have room to work with the content. Columns are most effective for short text fields, numbers, dropdowns, booleans, and images.


Nesting Groups

Groups can contain other groups, creating a hierarchical data structure. A top-level "Hero" group might contain a "Background" sub-group with image, overlay color, and opacity fields, plus a "Content" sub-group with heading, subheading, and CTA fields.

In the editor, nested groups appear as collapsible sections within their parent group. In the API response, they produce nested objects:

{
  "hero": {
    "background": {
      "image": { "url": "..." },
      "overlay_color": "#000000",
      "opacity": 0.5
    },
    "content": {
      "heading": "Welcome",
      "subheading": "Get started today",
      "cta_label": "Sign Up"
    }
  }
}

Nesting is useful when a group contains enough fields that further subdivision improves clarity. Keep nesting shallow — one or two levels deep is typical. Deeply nested groups make both the editor and the data structure harder to navigate.


Data Structure in the API

Groups create nested objects in the API response. A field placed inside a group is accessed through the group's handle as a parent key, rather than at the top level of the record.

A page model with a title field at the top level and an SEO group containing meta_title and meta_description produces this API shape:

{
  "title": "About Us",
  "seo": {
    "meta_title": "About Our Company | Brand",
    "meta_description": "Learn about our mission and team."
  }
}

Without the group, all three fields would be at the top level. With the group, the SEO fields are nested under the seo key. Your frontend accesses them as page.seo.meta_title and page.seo.meta_description.

This nesting is reflected in templates as well. In the site builder, you access grouped fields through the group handle:

<title><%= item.seo.meta_title %></title>
<meta name="description" content="<%= item.seo.meta_description %>">

And through the content API client:

const page = client.getPage('/about');
console.log(page.seo.meta_title);
// "About Our Company | Brand"

Moving and Ungrouping Fields

Fields within a group can be moved to a different group or ungrouped entirely — pulled back to the top level of the model — without losing existing content. This is a key property of groups: they organize data, but the underlying field data is preserved regardless of how you reorganize the grouping structure.

This means you can restructure your editor layout as your model evolves. If you start with a flat model and later decide to group SEO fields together, you can create a group and move the existing fields into it. The content editors have already entered is retained. If you later decide to split one group into two, or dissolve a group and move its fields elsewhere, the data follows the fields.

The practical implication is that groups are low-risk to add, change, or remove. You're not locked into a grouping structure once content exists. This is different from blocks, where changing the block model's structure affects all instances across the site. Groups are local to the model they belong to, and reorganizing them is a non-destructive operation.

Note that while the content data is preserved, the nesting structure in the API response does change when you move fields between groups. If your frontend accesses page.seo.meta_title and you move meta_title out of the seo group, the API path changes to page.meta_title. Your templates or frontend code will need to be updated to reflect the new structure.


When to Use Group vs Block

Groups and blocks both organize fields, but they serve fundamentally different purposes. The decision depends on whether you need reusability and composability or just editorial organization.

Use a group when:

  • The fields are specific to one model. An SEO group on a blog post model doesn't need to exist as a separate, reusable component.
  • The structure is fixed. Every page of this model should have these fields — editors can't add or remove groups.
  • You want to organize the editor visually. Groups are a zero-overhead way to cluster related fields and reduce visual clutter.
  • You need horizontal column layouts. Groups give you column control for arranging fields side by side.

Use a block when:

  • The same set of fields appears across multiple models. A CTA with heading, button label, and button URL used on five different page models should be a block — define it once, use it everywhere.
  • Editors need to add, remove, or reorder instances. Blocks inside dynamic block fields give editors composition control.
  • The component has its own visual template. Blocks get their own EJS template in the site builder.
  • You want structural changes to propagate site-wide. Modifying a block model updates every instance.

A useful heuristic: if you're duplicating the same set of fields across multiple models, extract them into a block. If the fields are unique to one model and just need better organization, use a group.


When to Use Group vs Collection

Groups and collections both nest fields, but groups produce a single object while collections produce a repeatable array.

Use a group when the structure appears once per record. A page has one set of SEO fields, one hero section, one contact details block. The data is singular — there's no "add another" action for editors.

Use a collection when editors need multiple items with the same structure. An FAQ page needs multiple question-answer pairs. A feature list needs multiple icon-title-description items. The data is plural — editors add as many items as they need.

The API response makes the distinction clear. A group produces a single nested object. A collection produces an array of objects:

{
  "seo": { "meta_title": "...", "meta_description": "..." },
  "faqs": [
    { "question": "...", "answer": "..." },
    { "question": "...", "answer": "..." }
  ]
}

seo is a group — one object, always present. faqs is a collection — an array with zero or more items.


What's Next

  • Collection Fields — Repeatable inline structures for variable-length lists.
  • Block Models — Reusable, composable content components for dynamic page sections.
  • Dynamic Blocks — Configuring allowed blocks, the editor experience, and layout governance.
  • Content Field Types — The full set of field types available in page, entry, and block models.
  • Page Models — How fields combine to define routable page content.
  • Entry Models — How fields combine to define reusable structured data.