We built DEV3 AI Page Builder for Gutenberg in PHP with a React editor integration. The model never writes markup. It returns a small, typed page plan, and the plugin builds the blocks itself.
Key design decisions
- A section plan, not HTML. The Google Gemini API answers with structured JSON: up to 10 sections drawn from 16 types (hero, features, pricing, FAQ, menu and others), each with capped strings, enums for layout, background and icons, and up to 12 items.
Schema::normalize_page() then re-checks every field: unknown types are dropped, list sections without items become plain content sections, plans without a price are removed, and exactly one pricing plan ends up featured.
- Every DEV3 block is dynamic. All 32
dev3pb/* blocks render on the server. Containers save only <InnerBlocks.Content /> and leaves save null, so the editor has no stored wrapper HTML to compare and validation cannot fail on them.
- Byte-exact core blocks. The text inside sections uses core heading, paragraph, list, buttons, image and details blocks.
Layout\Block builds each one as a parsed-block array whose HTML matches that block's own save() output, down to class order and newlines, and serialize_block() writes it out. PHPUnit asserts the exact strings.
- Rebuild on insert. In the editor, generated markup is parsed and every block is rebuilt with
createBlock(), so the editor re-serialises it with its own save functions before anything is stored.
- The server never trusts client markup. "Create draft page" sends the plan back, not HTML; the server normalises it again and rebuilds the blocks. Only the hero heading becomes an H1.
- Regenerate one section. Each generated section carries an
aiType attribute. Regeneration summarises the current section as indented plain text, sends it with the user's instruction, and swaps in a new section of the same type while the rest of the page stays as it is.
Architecture
Block definitions live in PHP and the editor reads them from server data, so attributes have one source of truth. A brand kit (colours, fonts, radius, voice) becomes CSS custom properties, can be added to the theme.json palette and is passed into every prompt; a WCAG contrast table checks the saved colours. Five template kits (landing, SaaS, agency, shop, restaurant) with eight pages, and a library of more than 40 ready-made sections, are built from the same section plans as the AI output. An SEO pass reads headings, images and links back out of the blocks and syncs titles with Yoast SEO and Rank Math. The API client, encrypted key storage, usage caps and logs come from a shared core used across DEV3's plugins.