Web Pages

A web page is a URL, a short flow and a template. The server sends finished HTML, and buttons and forms update only the part of the page that changed: one row, one counter, the errors of one form.

A page answers two kinds of request

Each kind starts its own flow in the same blueprint.

RequestStartsAnswers with
Opening the page (GET /shop)web_pageThe whole page, from web_render.
Clicking a button or sending a form on that page (POST /shop)The web_action whose name the button carriesOnly the changes: replace this row, remove that one, show these field errors.

When a visitor deletes a row, this is all that crosses the network on the way back. The script in the page applies it, and nothing else on the page moves:

The answer to a delete
{"ops": [{"op": "remove", "key": "p1"}]}

An action is posted to the page's own URL, so the page's scopes decide first who may use it. An action can carry scopes of its own. An action without them is allowed only for visitors every page of the blueprint allows, so a public page is never the way in to an action meant for an admin page in the same blueprint. A request from another website is refused. Escaping and Security has the rules.

web_render also works outside a web page: in the flow of an API endpoint it answers that request with the finished HTML. That page has no script and no actions.

What you get without building it

  • A page search engines can read. The title, description, canonical link, Open Graph tags, Twitter card, hreflang links and structured data are in the HTML when it leaves the server. See SEO and Sharing.
  • Escaping that follows your markup. A value in text, a link, a script or a style attribute is written safely for that place, and a template that cannot be made safe refuses to compile. See Escaping and Security.
  • A Content Security Policy with a fresh nonce on every page, so a string that sneaks into your HTML cannot run as a script.
  • Forms that check themselves. Required fields, email addresses, patterns and lengths are judged in the browser, with no request. Your server's own messages land next to the right field. See Forms and Validation.
  • Forms that survive without JavaScript. A plain form post runs the same action and sends the visitor back to a page.
  • Loading states and small interactions. Spinners, disabled buttons, confirm dialogs, optimistic removal and show or hide toggles come from a few attributes. See the Markup Reference.
  • Speed on every request. Templates compile once, unchanged pages answer with a 304, and links a visitor hovers load before the click. See Speed and Caching.
  • One page in many languages. A URL per language, hreflang and og:locale written for you, translations, and numbers and money in the page's language. See Languages.
Web pages replace state pages and UI components for new work State pages and UI components keep running, but new pages should be web pages. They hold no state on the server between requests and need no React and no WebSocket. Typing into a form costs nothing, because what the browser can judge never reaches the server. Migrating from State Pages shows which web block replaces what, what has no direct replacement, and a safe order to move a page in.

Where to go in this section

Next steps

Your First Page From an empty blueprint to a working URL in five minutes. Tutorial: A Small Webshop Everything in this section used together, step by step. Migrating from State Pages Which web block replaces what, for pages you already have.

Frequently asked

Can I build a website or webshop with RUAL blueprints?

Yes. A web_page block gives a URL a flow, and web_render renders its template on the server into a complete HTML page with title, meta description, canonical link, Open Graph and Twitter tags, hreflang links and JSON-LD. Templates use Mustache, the same syntax as mail templates, and shared pieces such as a layout, header or product card are stored templates used by name.

Should I use web pages or state pages in RUAL?

Web pages. State pages and UI components are deprecated: existing pages keep running, but new work should use the web blocks, which send a complete page from the server with its SEO tags already in it, and update only what changed. The migration guide shows which web block replaces what.