Skip to main content
A gavAI page is a JSON document describing a tree of blocks. PageBlocks are the ten block types that tree can contain — NavShell, Hero, Form, Table, and the rest. By the end of this page you will know what a block is, how blocks compose into a complete page, and where to look up the props for any individual block. The point of the design: every page is data, not code. You can GET a page, edit the JSON, and PATCH it back — no build step, no deploy. The runtime takes the document and renders it: server-rendered HTML on first load, then a WebAssembly bundle in the browser for interactivity.

A first example

Here is a complete page document — a marketing landing page with navigation, a hero, a feature grid, and a footer:
landing.json
{
  "version": "v0.4",
  "metadata": { "slug": "landing", "title": "Acme Co." },
  "schema": {},
  "tree": {
    "block": "NavShell",
    "props": {
      "brand_name": "Acme Co.",
      "variant": "topbar",
      "items": [{ "label": "Home", "href": "/" }, { "label": "Pricing", "href": "/pricing" }]
    },
    "children": [
      { "block": "Hero", "props": { "headline": "Welcome to Acme", "cta_label": "Sign up", "cta_href": "/signup" } },
      { "block": "FeaturesGrid", "props": { "columns": 3, "items": [] } },
      { "block": "Footer", "props": { "copyright": "© 2026 Acme Co.", "groups": [] } }
    ]
  }
}
Three things are happening. version pins the document schema revision so the runtime knows how to interpret the fields. metadata carries the URL slug and HTML title. tree is a single root block (NavShell) wrapping the page’s sections as children. Each child names a block type, carries its configuration in props, and may itself contain further nested blocks.

The mental model

Think of a block as a named, typed UI primitive. The name says what kind of section it is (Hero, Form). The props are its configuration (headline, cta_href, schema_table). The tree is the page. Two properties fall out of this shape. Pages are portable — the same JSON renders the same page in any workspace running the same runtime version. And pages are AI-friendly — a language model can read the tree, propose a JSON Patch, and round-trip an edit reliably, which is why the Builder MCP exposes block schemas as introspection tools. The analogy has a limit. Blocks are not React components you can write inline — you cannot ship a custom block type by dropping a .tsx file in your repo. The block catalogue is closed; new types ship with the runtime. What you customize is the composition and the props.

The ten block types

The first six are presentational — pure layout with no data binding. The last four are data-bound — they read or write rows in a schema table you declare on the page document.

Beyond the core ten

The ten blocks above cover the structural skeleton of a page. The runtime ships a broader palette of section and interactive blocks that you compose as children inside the structural ones. They share the same JSON shape — block, props, children — and the same theming, visibility, and analytics props. Marketing sections are presentational blocks meant for landing-page content above and below the structural shell. The catalogue covers the layouts you reach for when describing a product: an alternating features section, a card-style bento grid, a callout band, a comparison table, an FAQ accordion, a logo cloud, a pricing table, a pull quote, a stats row, a testimonials carousel, and a newsletter sign-up. Each one is a typed block with its own props — you do not stitch them out of raw HTML. Interactive blocks are data-bound surfaces tuned for end-user-facing apps that go beyond a basic list-and-detail view. The catalogue includes a calendar view for date-indexed records, an intake form tuned for multi-step lead capture, and a card-style list view variant for record browsing where the table block would feel heavy. Both families render through the same pipeline as the core ten: server-side HTML on first load, then a WebAssembly bundle in the browser for interactivity. A page that mixes a Hero, a marketing Pricing section, and a data-bound Calendar view is a single document, not three.

Common props

Every block accepts these four optional props in addition to its own type-specific ones.

How blocks pick up the theme

Every visual property a block exposes — color, spacing, type scale, corner radius — resolves through workspace theme tokens, not hard-coded values. Change one token and every block instance picks up the new value on the next render. When you need a one-off tweak on a single block, use class_overrides on that instance — it layers on top of the resolved token values and does not affect any other block. See Theme for the full token model.

Where to go next