Blockstudio
BlocksAttributes

Custom Fields

Custom fields let you define reusable field groups that can be referenced across multiple blocks. Think of them as field templates: define once, use everywhere.

File System Registration

Create a field.json file inside a fields/ directory in your blockstudio directory:

theme/
└── blockstudio/
    └── fields/
        └── hero/
            └── field.json
fields/hero/field.json
{
  "$schema": "https://blockstudio.dev/schema/field",
  "name": "hero",
  "title": "Hero Section",
  "attributes": [
    { "id": "heading", "type": "text", "label": "Heading", "default": "Hello World" },
    { "id": "description", "type": "textarea", "label": "Description" },
    { "id": "enabled", "type": "toggle", "label": "Enabled" }
  ]
}

PHP Filter Registration

Register custom fields programmatically using the blockstudio/fields filter:

add_filter('blockstudio/fields', function ($fields) {
    $fields['cta'] = [
        'title'      => 'Call to Action',
        'attributes' => [
            ['id' => 'text', 'type' => 'text', 'label' => 'Button Text'],
            ['id' => 'url', 'type' => 'text', 'label' => 'URL'],
        ],
    ];
    return $fields;
});

Usage in block.json

Reference a custom field using the custom/{name} type:

block.json
{
  "blockstudio": {
    "attributes": [
      { "type": "custom/hero" }
    ]
  }
}

This expands inline to the fields defined in the custom field definition. The expanded fields use their original IDs (heading, description, enabled).

ID Structure

Use idStructure to prefix or transform field IDs. The {id} placeholder is replaced with the original field ID:

block.json
{
  "blockstudio": {
    "attributes": [
      { "type": "custom/hero", "idStructure": "hero_{id}" }
    ]
  }
}

This produces fields with IDs: hero_heading, hero_description, hero_enabled.

Overrides

Customize individual fields per-instance using overrides. Keys are the original field IDs from the definition:

block.json
{
  "blockstudio": {
    "attributes": [
      {
        "type": "custom/hero",
        "idStructure": "hero_{id}",
        "overrides": {
          "heading": { "default": "Welcome", "label": "Title" },
          "enabled": { "id": "active" }
        }
      }
    ]
  }
}

Override properties are merged on top of the original field definition. An id override bypasses the idStructure pattern. In the example above, enabled becomes active instead of hero_enabled.

Multiple Custom Fields

You can use multiple custom fields in a single block, alongside regular fields:

block.json
{
  "blockstudio": {
    "attributes": [
      { "id": "intro", "type": "text", "label": "Intro" },
      { "type": "custom/hero", "idStructure": "hero_{id}" },
      { "type": "custom/cta", "idStructure": "cta_{id}" }
    ]
  }
}

Nesting

Custom fields work inside groups, tabs, and repeaters:

block.json
{
  "blockstudio": {
    "attributes": [
      {
        "type": "group",
        "id": "content",
        "title": "Content",
        "attributes": [
          { "type": "custom/hero", "idStructure": "hero_{id}" }
        ]
      }
    ]
  }
}

Additional Discovery Paths

Use the blockstudio/fields/paths filter to add additional directories for field discovery:

add_filter('blockstudio/fields/paths', function ($paths) {
    $paths[] = get_stylesheet_directory() . '/blockstudio/fields';
    return $paths;
});

On this page