> From the [Strife developer docs](https://strife.app/docs/reference/field-reference/fields.tabs). Every page is listed in [llms.txt](https://strife.app/docs/llms.txt).

# fields.tabs()

Structural tab-group layout. Takes an array, not an options object — the only builder shaped this way.

Tab-group layout — a structural field that _contains_ its fields (Payload-style), grouping them into tabs in the editor UI. Maps to a `{ name: 'str-tab-group', type: 'str-tab-group' }` editor (name and type match, same quirk as [`fields.radioGroup()`](https://strife.app/docs/reference/field-reference/fields.radiogroup.md)); its children are emitted as flat editors with `attributes.tabGroup` membership.

> [!WARNING]
> `fields.tabs()` doesn't take an options object at all — its only parameter is the array of tab definitions. There's no `label`, `description`, or any of the other common options here, and the wire label is hardcoded to `"Tab group"` internally (not configurable from the DSL).

Strife stores tab data **flat** on the parent document, so the children are hoisted to the parent content shape — `Infer<>` merges them in and drops the tabs field itself. There is no named-tab data nesting in Strife.

## Example

```ts
fields: {
  tabGroup: fields.tabs([
    {
      label: 'Content',
      fields: { heading: fields.text({ label: 'Heading' }) },
    },
    {
      label: 'SEO',
      fields: { meta: fields.serp({ label: 'SEO' }) },
    },
  ]),
}
// Infer<> → { heading: string; meta: Serp }  — the `tabGroup` key itself doesn't appear
```

## Parameter

`fields.tabs(defs)` takes a single array parameter, `defs: TabDef[]`:

| `TabDef` field | Type                              | Required | Description                                                                                                         |
| -------------- | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `label`        | `string`                          | Yes      | Tab label shown to editors.                                                                                         |
| `fields`       | `Record<string, FieldDescriptor>` | Yes      | The fields shown under this tab. Hoisted flat into the parent content shape — same rules as any other `fields` map. |
| `description`  | `string`                          | No       | Optional text shown inside the tab, above its fields.                                                               |
| `value`        | `string`                          | No       | Wire value / id for the tab. Defaults to the slugified label.                                                       |

## Output type

`never` for the `tabs()` field itself (it carries no data of its own). Its children's output types are hoisted into the parent's `Infer<>` shape directly — a field declared inside a tab reads exactly the same as if it were declared at the top level of `fields`.

## See also

* [Tab Group](https://strife.app/docs/reference/fields/tab-group.md) — the same editor, documented from the Strife Studio UI side.
