Alpha: Ships on npm at 7.0.0-alpha.07.0.0-alpha.0

Pages are data

A page is one JSON record of words and choices, never markup. What that buys an agent, and the four layers that turn it into HTML.

View as JSON

A page is one JSON record that PageSchema accepts or refuses, and renderPage turns it into one HTML document. The record holds content only: no markup, no class names, no CSS. Open the Record tab to read the same page as data:

From Harbor tides › homequaypointOpen the frame

What a record buys an agent

An agent writing markupAn agent writing a record
Redraws the layout on every editChanges words; the layout is the Section type's
Drifts from the brand page by pageEvery page wears the one Theme it names
Produces a diff of tags and classes to reviewProduces a JSON diff of the words that changed
Breaks the layout with a long headlineIs refused at the field, with its maximum, before anything renders

The smallest record

25 lines; PageSchema.parse accepts it
{
  "theme": "quaypoint",
  "title": "Harbor tides",
  "description": "Tide tables for every berth.",
  "frame": "none",
  "sections": [
    {
      "kind": "hero", "shell": { "inset": "contained", "density": "hero" },
      "block": {
        "type": "hero", "layout": "centered", "stack": 560,
        "title": "Every berth, every tide.",
        "lede": "One call returns the tide table for any berth.",
        "actions": [], "fine": []
      }
    },
    {
      "kind": "band", "shell": { "inset": "contained", "density": "section" },
      "block": { "type": "statement", "text": "A tide table is a *promise*." }
    },
    {
      "kind": "section", "shell": { "inset": "contained", "density": "section" },
      "block": { "type": "command-row", "command": "npm i harbor-tides" }
    }
  ]
}
FieldSays
themeWhich bundled Theme the page wears
frameThe frame around every section: none, one ruled sheet, or a split with an aside
sectionsThree to twenty sections, in page order
kindWhat the section is to its neighbors; it picks the landmark and the divider
shell.inset, shell.densityThe section's width and its vertical pace
block.typeThe Section type that lays the content out
stackThe width in pixels below which the hero's actions stack

Four layers

Block is the renderer's word for a Section type's code; these docs say Section type everywhere else. Each layer owns one thing and never reaches into another.

LayerHoldsNever knows
BlockOne Section type's layout: one root element, colors by roleWhat is painted behind it, its neighbors, the Theme, the page
ShellWhat is painted behind and between: surface, background, inset, density, stickiness, the frameWhat the content says
ThemeTokens and policies, compiled to custom propertiesWhich page it dresses
CompositionThe record: Theme, frame and sectionsMarkup and CSS

The rules the layers keep

RuleIt prevents
No model writes markup or CSS; a Section type is drawn once by handA page that re-guesses its design on every edit
A token never changes layout; a layout change is a variantA Theme that breaks a page it never saw
Painted behind content is shell; positioning content is blockTwo layers fighting over one box
A Section type never knows its neighbors; the composer derives each dividerA divider right between two sections and wrong between two others
Every string is boundedA headline three times the length the design was drawn for

Edit with the schema

PageSchema.toJSONSchema() writes every bound as maxLength, minItems and maxItems, the schema this site serves at /schema.json:

import { PageSchema } from '@mdxui/site';

const schema = PageSchema.toJSONSchema();

A record may open with a $schema key naming that address; PageSchema strips unknown keys as it parses.

startupbuilder.dev defines the Page; the record is how mdxui holds one. Page maps each part, and How mdxui fits a Business places it in a Business.

On this page