Turning AI output into UI: components instead of arbitrary HTML
Validate model data, map it to allowed components, and design loading and failure states.
Checking local voices…

In brief
Validate model data, map it to allowed components, and design loading and failure states.
On this page
Displaying a model response and allowing a model to execute interface code are different decisions. For a personal application, a small set of predefined components with validated data is an inspectable starting point. This is an application design example, not a measured production performance result.
Define the data contract first
For example, let the model propose only a summary, checklist or source card. Define required fields, text limits and allowed link formats for each type. Reject an unknown type or invalid address instead of rendering it. Do not dynamically execute component or package names supplied by a model.
React supports rendering ordinary text content. Its raw HTML insertion feature introduces additional risks with untrusted data. Validation alone does not make arbitrary HTML safe; when raw HTML is unnecessary, leaving that path closed is easier to reason about.
Design waiting and failure states
Show which part is not ready while loading. Suspense can provide a fallback for supported data sources or lazily loaded components; it does not automatically handle an ordinary request inside an effect. A transition does not make every asynchronous operation safe or fast either. Preserve responsive typing rather than moving controlled text-input updates into a transition.
Try your own card contract
A safe simulation. No real requests, messages or payments; choices stay on this page.
Allowed types: summary, source. source requires an HTTPS URL. No code is executed.
A validated card.
Keep acceptance tests small
Try a valid card, a missing required field, excessive text and a disallowed link. Check loading and failure messages with assistive technology. Obtain separate approval if a user action changes data; model output is not authority. The checklist below reviews an interface contract and does not generate executable code.
Start with a dictionary of three cards
A first prototype might need only a summary card, a checklist and a source card. Give the summary a title and short text, limit the checklist to a bounded number of items, and require the source card to carry a description and address. Do not let the model expand this dictionary itself. Treat an unknown type as unsupported output so the interface remains within a behavior space that a developer and user can understand.
For a source card, check that the address matches the link formats the application permits. Consider whether the visible label accurately describes the destination. A length limit alone cannot establish that a link is trustworthy. Where the product requires it, add a known-domain policy or an explicit indication that a link leaves the site. These are application decisions rather than abilities that come automatically with structured output.
Keep presentation separate from permission
A card displaying a Send label should not automatically acquire permission to send a message. A visual proposal, the eventual operation and the user’s decision belong to separate layers. If the model prepares an action, show the final destination and payload before execution. Preserve that boundary as later versions introduce more tools; an interface should not silently turn a suggestion into an external effect.
Even a shopping-list example benefits from this distinction. A model can propose products, while submitting an order to a store is another operation entirely. If one card dictionary silently combines both behaviors, the interface can do more than the user expects. Permissions established for an earlier feature do not automatically cover a newly introduced action. Revisit the boundary whenever the system gains another capability.
Make malformed output a designed state
Do not build solely around an attractive valid response. Define behavior for a missing title, an empty checklist, an unusually long word, an invalid URL and an unknown type. The failure panel should not cause a disruptive page jump, and the original question should remain available. Check whether keyboard users can reach the new result and whether status changes make sense to a screen reader.
Finally, keep a short versioned record of supported types, limits and rejected examples. Rerun the same examples after a model or prompt change. The goal is not to accept every response; it is to explain consistently which responses the application accepts and why. That contract becomes a useful design artifact when moving from an impressive first demonstration to a small product that somebody must maintain.
Sources
Next step
Continue with Learning n8n locally: the license and the real costs, or download this guide and its working notes as a PDF.
Optional audio. No autoplay or third-party player.
Frequently asked questions
Is model-generated JSON safe?
JSON is a data format, not a security guarantee. It can contain unexpected types, oversized values or unwanted links. Validate the structure and map it only to known components, with a clear failure state when validation fails.
Why not let the model generate HTML directly?
This example aims for a small, inspectable interface. Predefined components offer a narrower behavior space. A genuine raw-HTML requirement needs a separate threat assessment and an appropriate sanitization strategy rather than an assumption that generated markup is harmless.
Should the model choose new packages for new cards?
No. Define supported types in the application. Do not download or dynamically execute a package or component name supplied by a model. New component types should go through normal product development and validation.
How should invalid output appear?
Explain that the response could not be displayed without exposing hidden context or internal details. Preserve the previous valid result where appropriate and offer recovery. Verify that an error does not erase the user’s input.
Does this prove the AI answer is correct?
No. A schema checks structure; source review examines the evidence behind claims. A well-formed, attractive card can still contain incorrect information. Keep those assessments separate.