---
title: "Building with AI · RUAL Documentation"
description: "Let an AI agent write your pages: what to ask for, how stored templates and short flows keep its work reviewable, and the habits that keep pages consistent."
canonical: https://docs.rual.nl/web/with-ai
language: en
---

# Building with AI

Web pages are designed to be written by an AI agent as easily as by hand: a page is a template plus a short flow, and every web block carries a precise description of what it does in the block catalog. Ask for the result you want, and review the page and the flow it stages.

## Templates and short flows suit an agent

- **A template is plain text in a syntax agents already know,** HTML with Mustache. There are no component trees to wire block by block.

- **A flow stays short.** A search, a render, an action or two: little enough to read in full when you review it.

- **Mistakes stop early.** A template that does not compile says so with its line and column, and a bad block or pin fails the [dry run](https://docs.rual.nl/engine/editing-with-ai).

- **Escaping is not its job.** The engine escapes each value for its place, so a page written quickly is still safe, as long as it stays away from triple braces around visitor input.

- **The page is the backend.** The agent does not write a frontend that calls an API. The page's own request is the backend and the frontend at once, so there is one thing to build and to check.

## Ask for the result, and name the data

Describe what the visitor sees and does, and which storages hold the data. The agent can create the stored templates through the API and write the blueprint with the web blocks.

#### Ask for this

"A product page at `/products/:slug` for every product in the `products` storage, with a reviews list and an add-to-cart form. Public. Reuse the `main` layout. Show field errors next to the form."

#### Not this

"Add a web_page, then a function_search, then wire array into items." That asks the agent to draw a canvas, and takes away what it is good at. Say what the page is for, and review the blocks it picks.

Things worth saying out loud, because an agent cannot guess them:

- who may open the page, and who may run each action;

- the URL, and the languages if there is more than one;

- which existing layout and partials to use;

- what a page should do when the document is not there: a 404, for most.

## Point the agent at the docs and the catalog

- **[/llms.txt](https://docs.rual.nl/llms.txt)** is the index of these docs for an agent, and every page here also has a Markdown version.

- **The block catalog** describes every web block for an agent: what each pin means, the rules that fail, and what the block answers. The same text is what you read under each block in the [block reference](https://docs.rual.nl/block-types).

- **[Editing with an AI Agent](https://docs.rual.nl/engine/editing-with-ai)** is the way in: export the source, edit it, dry run it, stage it. The source API cannot make a change live: the save in RUAL Studio does that, so you always review it first.

- **[Blueprint Language](https://docs.rual.nl/engine/blueprint-language)** is what the agent reads and writes. [The webshop tutorial](https://docs.rual.nl/web/build-a-shop) is a full example in it to show the agent.

## Three habits keep its pages consistent

### Keep shared pieces in stored templates

The header, the footer, a product card, a table row: store them as `web` templates, so a page and its actions render them identically. An agent that copies a row into an action's render block gets it right today, and it drifts the first time someone edits one of the two. Tell it which [stored pieces](https://docs.rual.nl/web/layouts-and-partials) exist, and ask it to add new shared ones there.

### Give everything an action changes a data-key or an id

An update block finds its element by `data-key` or by a CSS selector. A row from [`web_foreach`](https://docs.rual.nl/block-types/web/web_foreach) has its key already. For a counter, a total or a message place, ask for an `id` that says what it holds, such as `#cart-count`. An update aimed at an element that is not there is not an error on the server, so this is the first thing to check when nothing seems to happen.

### Prefer one action per intent

Ask for `add`, `save` and `delete`, not one action with a switch on a `mode` field. Each flow stays short enough to read, each can carry its own scopes, and a button says what it does.

## What to check when you review

- **Scopes.** Is every page and action open to exactly who should use it? A public action in a blueprint with an admin page needs its own `*public`, and one that changes data probably should not be public.

- **Triple braces.** Each `{{{x}}}` must hold HTML the flow built, never something a visitor typed.

- **Checks in the action.** Browser checks are a convenience: anything that matters is checked again on the server.

- **The page's source.** Open it and read the head: title, description and canonical tell you quickly whether the pins were wired.

## Next steps

- [Editing with an AI Agent](https://docs.rual.nl/engine/editing-with-ai): Export, edit, dry run and stage: the source API step by step.

- [Tutorial: A Small Webshop](https://docs.rual.nl/web/build-a-shop): A complete blueprint to give an agent as an example.

- [Layouts and Partials](https://docs.rual.nl/web/layouts-and-partials): Where the shared pieces live.
