Skip to main content
Starting with WordPress 5.8, the recommended way to register block types is using the block.json metadata file. This file serves as the canonical definition for both PHP (server-side) and JavaScript (client-side) registration.

Basic example

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "my-plugin/notice",
	"title": "Notice",
	"category": "text",
	"icon": "star",
	"description": "Shows warning, error or success notices",
	"keywords": ["alert", "message"],
	"attributes": {
		"message": {
			"type": "string",
			"source": "html",
			"selector": ".message"
		}
	},
	"supports": {
		"align": true
	},
	"editorScript": "file:./index.js",
	"style": "file:./style.css"
}

Block properties

Required properties

name
string
required
The unique identifier for the block. Must be structured as namespace/block-name where namespace is your plugin or theme name. Can only contain lowercase alphanumeric characters, dashes, and one forward slash.
{ "name": "core/heading" }
title
string
required
The display title for your block shown in the Inserter and other areas. Can be translated.
{ "title": "Heading" }

Optional properties

apiVersion
number
default:"1"
The version of the Block API used by the block. The most recent version is 3, introduced in WordPress 6.3.
{ "apiVersion": 3 }
category
string
Blocks are grouped into categories in the Inserter. Core categories include: text, media, design, widgets, theme, and embed.
{ "category": "text" }
icon
string
An icon to identify the block. Can be any WordPress Dashicon slug or custom SVG.
{ "icon": "star" }
description
string
A short description shown in the block inspector. Can be translated.
{ "description": "Introduce new sections and organize content" }
keywords
string[]
default:"[]"
Search terms to help users discover the block. Can be translated.
{ "keywords": ["alert", "message"] }
version
string
The current version of the block, used for cache invalidation.
{ "version": "1.0.3" }
textdomain
string
The gettext text domain for internationalization.
{ "textdomain": "my-plugin" }
attributes
object
default:"{}"
Defines the structured data needs of the block. See Attributes for details.
{
  "attributes": {
    "cover": {
      "type": "string",
      "source": "attribute",
      "selector": "img",
      "attribute": "src"
    }
  }
}
providesContext
object
default:"{}"
Context provided for descendent blocks. Maps context name to attribute.
{
  "providesContext": {
    "my-plugin/recordId": "recordId"
  }
}
usesContext
string[]
default:"[]"
Array of context names to inherit from ancestor blocks.
{ "usesContext": ["message"] }
selectors
object
default:"{}"
Custom CSS selectors for theme.json styles. Available since WordPress 6.3.
{
  "selectors": {
    "root": ".my-custom-block-selector",
    "typography": {
      "root": ".my-custom-block-selector > h2"
    }
  }
}
supports
object
default:"{}"
Features enabled for the block. See Supports for details.
{
  "supports": {
    "align": true,
    "color": {
      "background": true,
      "text": true
    }
  }
}
styles
array
default:"[]"
Alternative block styles. The label property can be translated.
{
  "styles": [
    { "name": "default", "label": "Default", "isDefault": true },
    { "name": "outline", "label": "Outline" }
  ]
}
example
object
Structured data for the block preview in the Inspector.
{
  "example": {
    "attributes": {
      "message": "This is a notice!"
    }
  }
}
variations
object[]
Block variations that share common functionality. Available since WordPress 5.9.
{
  "variations": [
    {
      "name": "example",
      "title": "Example",
      "attributes": { "level": 2 },
      "scope": ["block"]
    }
  ]
}
parent
string[]
Restricts block to only be available nested within specified blocks.
{ "parent": ["my-block/product"] }
ancestor
string[]
Makes block available anywhere within specified block subtrees. Available since WordPress 6.0.
{ "ancestor": ["my-block/product"] }
allowedBlocks
string[]
Specifies which blocks can be direct children. Available since WordPress 6.5.
{ "allowedBlocks": ["core/list-item"] }

Asset properties

editorScript
string | string[]
Scripts enqueued only in the editor context. Can be a registered handle or file path.
{ "editorScript": "file:./index.js" }
script
string | string[]
Scripts enqueued in both editor and frontend.
{ "script": "file:./script.js" }
viewScript
string | string[]
Scripts enqueued only on the frontend. Available since WordPress 5.9.
{ "viewScript": ["file:./view.js", "shared-script"] }
viewScriptModule
string | string[]
Script modules enqueued only on the frontend. Available since WordPress 6.5.
{ "viewScriptModule": "file:./view.js" }
editorStyle
string | string[]
Styles enqueued only in the editor.
{ "editorStyle": "file:./index.css" }
style
string | string[]
Styles enqueued in both editor and frontend.
{ "style": ["file:./style.css", "shared-style"] }
viewStyle
string | string[]
Styles enqueued only on the frontend. Available since WordPress 6.5.
{ "viewStyle": "file:./view.css" }
render
string
PHP file for server-side rendering. Available since WordPress 6.1.
{ "render": "file:./render.php" }
The file receives three variables:
  • $attributes (array) - Block attributes
  • $content (string) - Block default content
  • $block (WP_Block) - Block instance

Asset file paths

File paths must be prefixed with file: and are relative to the block.json location.

Dependency files

For script and style assets, WordPress automatically detects .asset.php files:
build/
├─ block.json
├─ index.js
└─ index.asset.php
The .asset.php file should return:
<?php
return array(
	'dependencies' => array('react', 'wp-blocks'),
	'version' => '3be55b05',
);

Internationalization

WordPress can automatically translate fields marked as translatable when the textdomain property is set. Translatable fields include:
  • title
  • description
  • keywords
  • styles[].label
  • variations[].title
  • variations[].description
  • variations[].keywords

PHP translation

In PHP, properties are wrapped in _x() function calls:
$metadata = array(
	'title' => _x('My block', 'block title', 'my-plugin'),
	'description' => _x('My block is fantastic', 'block description', 'my-plugin'),
);

JavaScript translation

import { registerBlockType } from '@wordpress/blocks';
import metadata from './block.json';

registerBlockType( metadata, {
	edit: Edit,
	// Properties are automatically wrapped with _x()
} );

Frontend asset enqueueing

Assets specified in script, viewScript, style, and viewStyle are only enqueued when the block is present on the page, optimizing performance.

Build docs developers (and LLMs) love