Every wpTruss custom block is a folder containing exactly 5 files. No build step is required to run a block. The folder is zipped and uploaded via the admin.
Required File Structure
your-block-slug/
├── block.json Block metadata. Declares attributes, panels, and the editor script.
├── index.js Block editor UI. Plain IIFE JavaScript — no JSX, no build step.
├── index.asset.php Dependency declaration. WordPress loads these scripts before index.js.
├── render.php Server-side render. Reads $attributes and outputs escaped HTML.
└── style.css Frontend + editor styles. --wpt-* tokens only. Scoped selectors only.
The folder name becomes the block slug. Use lowercase with hyphens only: feature-card, hero-banner, faq-accordion.
Block Folder Location
Installed blocks must live directly inside custom-blocks/. There are no subfolders within a block folder. Placing files in a subfolder means wpTruss will never find the block.
✅ CORRECT: custom-blocks/feature-card/block.json
❌ WRONG: custom-blocks/feature-card/src/block.json
❌ WRONG: custom-blocks/my-blocks/feature-card/block.json
The custom-blocks/ scanner looks one level deep only.
How the Five Systems Connect
Every block integrates with three shared systems automatically:
- Design Token Engine —
style.cssconsumes--wpt-*tokens. The validator enforces this. - Element Registry —
index.jscallswindow.wptElements.buildElementClasses()to get shared element class strings from the registry. - Panel Registry —
block.jsondeclareswptPanelsandindex.jsreadswindow.wptPanelRegistryfor live panel option sets.