block.json is the block’s registration file. WordPress reads it to register the block type, its attributes, and its scripts. wpTruss reads the wptPanels key to inject shared inspector panels into the block editor at runtime.
Minimum Valid block.json
{
"name": "wptruss/feature-card",
"title": "Feature Card",
"description": "A single feature card with icon, heading, and description.",
"category": "wptruss",
"icon": "grid-view",
"version": "1.0.0",
"apiVersion": 3,
"editorScript": "file:./index.js",
"style": "file:./style.css",
"render": "file:./render.php",
"wptPanels": {
"structure": true,
"spacing": true,
"layout": true
},
"attributes": {
"headingLevel": { "type": "string", "default": "h3" },
"semanticRole": { "type": "string", "default": "article" },
"blockPadding": { "type": "string", "default": "xl" },
"blockGap": { "type": "string", "default": "md" },
"spacingBottom": { "type": "string", "default": "none" },
"hideOnMobile": { "type": "boolean", "default": false },
"hideOnTablet": { "type": "boolean", "default": false },
"hideOnDesktop": { "type": "boolean", "default": false },
"textAlign": { "type": "string", "default": "left" },
"elementOverrides": { "type": "object", "default": {} },
"heading": { "type": "string", "default": "" },
"description": { "type": "string", "default": "" }
}
}
Key rules:
namemust follow thenamespace/slugformat. Usewptruss/as the namespace for all platform blocks.apiVersionmust be3.renderpointing tofile:./render.phpis required for all wpTruss blocks. Thesave()function inindex.jsalways returnsnull.headingLevelandsemanticRoleare required attributes — the block validator rejects blocks missing either.elementOverridesis required if you use any element registry element in the block. Omitting it means per-block overrides can never be stored.
Mandatory Attributes — Full Set
Include all of these in every block that uses the standard panel set. Do not strip any attribute from this group — the Panel Registry resolves classes against these exact keys at runtime:
"attributes": {
"headingLevel": { "type": "string", "default": "h2" },
"semanticRole": { "type": "string", "default": "section" },
"themeMode": { "type": "string", "default": "light" },
"backgroundColor": { "type": "string", "default": "light" },
"blockPadding": { "type": "string", "default": "3xl" },
"blockGap": { "type": "string", "default": "xl" },
"spacingBottom": { "type": "string", "default": "none" },
"tabletColumns": { "type": "string", "default": "1" },
"hideOnMobile": { "type": "boolean", "default": false },
"hideOnTablet": { "type": "boolean", "default": false },
"hideOnDesktop": { "type": "boolean", "default": false },
"textAlign": { "type": "string", "default": "left" },
"elementOverrides": { "type": "object", "default": {} }
}
wptPanels
wptPanels controls which shared registry panels are injected into the block’s inspector. Set a panel to true to include it, omit or set false to exclude it.
"wptPanels": {
"structure": true,
"spacing": true,
"layout": true
}
When a panel is enabled, the Panel Registry injects its current option set into the block at runtime. Adding a new heading level or spacing scale value to the registry propagates to every block that has that panel enabled — without editing individual block files.