---
title: 'Field Groups'
description: 'Reference and usage guidance for Field Groups.'
---

import { Callout } from 'nextra/components';

# Field Groups

Organize long edit forms by grouping attributes under tabs.

When a product, order, or other entity has many attributes, showing every field at once is hard to scan. Define `groups` on the entity and assign attributes with `group`. Groups change only how the form is laid out. They do not change the stored record, GraphQL, or list columns.

`entity.groups` and `attribute.group` are not the same as `entity.menu.group`. The menu property is the sidebar section.

## Prerequisites

- A Flexkit schema you can edit. See [Schemas](/docs/schema) and [Entity Reference](/docs/schema/entity-reference).

## Example

Define SEO and media groups on a product, then assign the related attributes:

```tsx
import { defineEntity } from '@flexkit/studio';

export const products = defineEntity({
  name: 'product',
  plural: 'products',
  display: 'name',
  menu: { label: 'Products', group: 'catalog' },
  groups: [
    { name: 'details', title: 'Details', default: true },
    { name: 'seo', title: 'SEO' },
    { name: 'media', title: 'Media' },
  ],
  attributes: [
    {
      name: 'name',
      label: 'Name',
      scope: 'local',
      dataType: 'string',
      inputType: 'text',
      group: 'details',
    },
    {
      name: 'sku',
      label: 'SKU',
      scope: 'global',
      dataType: 'string',
      inputType: 'text',
      group: 'details',
    },
    {
      name: 'metaTitle',
      label: 'SEO title',
      scope: 'local',
      dataType: 'string',
      inputType: 'text',
      group: 'seo',
    },
    {
      name: 'metaDescription',
      label: 'Meta description',
      scope: 'local',
      dataType: 'string',
      inputType: 'textarea',
      group: 'seo',
    },
    {
      name: 'images',
      label: 'Images',
      dataType: 'asset',
      inputType: 'relationship',
      group: ['media', 'seo'],
    },
  ],
});
```

An **All fields** tab is added automatically. It lists every attribute that is not field-`hidden`. Attributes without a `group` appear only there.

<Callout type="info">
  Set `default: true` on a group to open that tab first. If no group is marked default, Studio opens the first named
  group.
</Callout>

## Hide the All fields tab

The reserved name `all` is the All fields tab. Add it to `groups` and set `hidden: true`:

```tsx
import { defineEntity } from '@flexkit/studio';

export const products = defineEntity({
  name: 'product',
  plural: 'products',
  groups: [
    { name: 'details', title: 'Details' },
    { name: 'seo', title: 'SEO' },
    { name: 'all', hidden: true },
  ],
  attributes: [
    // ...
  ],
});
```

Ungrouped attributes then have no tab. Attributes that do not belong to any visible tab — ungrouped when All fields is hidden, or assigned only to a hidden group — are omitted from the form and from validation, so they do not block save. Assign every attribute you want editors to see.

## Conditional groups

Hide a group with a boolean or a synchronous callback. The callback receives `record` (unwrapped entity values), `value` (the same record), and `currentUser`.

Hide SEO from viewers:

```tsx
{
  name: 'seo',
  title: 'SEO',
  hidden: ({ currentUser }) => currentUser?.role === 'viewer',
}
```

<Callout type="warning">
  Group `hidden` callbacks must be synchronous. They run in Studio only and are stripped on JSON deploy, the same as
  field `hidden` and `validation`.
</Callout>

## Reference

### Entity `groups`

Array of group objects:

| Property  | Type                                | Description                                                                                       |
| --------- | ----------------------------------- | ------------------------------------------------------------------------------------------------- |
| `name`    | `string`                            | Unique id. Attributes use this in `group`. The reserved name `all` is the All fields tab.         |
| `title`   | `string`                            | Tab label. Required for custom groups. Optional for `all`; Studio uses `All fields` when omitted. |
| `icon`    | `JSX.Element`                       | Optional tab icon.                                                                                |
| `default` | `boolean`                           | Open this tab first. Defaults to `false`.                                                         |
| `hidden`  | `boolean` or `(context) => boolean` | Hide the tab.                                                                                     |

### Attribute `group`

`string` or `string[]`. The attribute appears in each listed group and in All fields.

## Related

- [Entity Reference](/docs/schema/entity-reference)
- [Attribute Reference](/docs/schema/attribute-reference)
- [Conditional Fields](/docs/schema/conditional-fields)


---

[View full sitemap](/docs/sitemap.md)
