Lessons from Embedding an LLM Inside a Drag-and-Drop Editor A developer building WebDigitize, an AI-powered website generator for Nigerian small businesses, found that embedding an LLM inside a drag-and-drop editor requires the model's output to be structurally valid, not just semantically good. By representing component schemas as a compact formal notation in the system prompt, they achieved reliable generation of valid JSON for the Puck editor, preventing hallucinated field names and broken components. When you integrate an AI generation step into a drag-and-drop editor, you face a problem that is rarely discussed in LLM tutorials: the model's output must be structurally valid, not just semantically good . A hallucinated CSS class name is a style regression. A hallucinated prop key in an editor schema is a broken component. This is a writeup of what I learned building WebDigitize, an AI-powered website generator and editor for Nigerian small businesses, using Puck https://github.com/measuredco/puck as the editor layer. Puck stores page state as a JSON document: { "root": { "props": {} }, "content": { "type": "HeroSection", "props": { "headline": "Fresh Bread, Delivered Daily in Lagos" } } , "zones": {} } Each entry in content maps to a React component registered in Puck's config: js const config: Config = { components: { HeroSection: { fields: { headline: { type: "text" }, subheadline: { type: "text" }, ctaLabel: { type: "text" }, ctaHref: { type: "text" }, }, render: { headline, subheadline, ctaLabel, ctaHref } =