A single source of truth for site structure
StructureSpec is an open standard for defining a site's structure as machine-readable JSON. The sitemap, page archetypes, navigation, and routing — all in one canonical file, composable from BlockSpec primitives and themed by BrandSpec tokens.
StructureSpec composes BlockSpec items into pages. The sitemap defines hierarchy; archetypes define the block sequence per page type; navigation references sitemap nodes by slug. One spec replaces sitemap diagrams, wireframe libraries, and page-level handoff documents.
The problem it solves
Site planning lives across half a dozen artefacts. The sitemap is a Miro board. The page templates are Figma frames. The navigation lives in a Google Doc. The block sequence per page is in someone's head.
Every artefact drifts from the others, and gets rebuilt from scratch on every project.
What it replaces
- Static sitemap diagrams in Miro or Lucid
- Wireframe libraries that drift from the design system
- Verbal handoffs about which blocks go on which pages
- Manual sitemap-to-CMS translation
- Drift between IA, design, and implementation
How it works
ProcessA StructureSpec file is a single .json document describing one site's structure. It references BlockSpec items by slug and is themed at render time by a BrandSpec.
-
Define the sitemap
Map out the site as a tree of pages. Each node has a slug, title, and an archetype reference — pointing at the archetype that describes its block sequence. Children nest recursively.
-
Define the archetypes
An archetype is a reusable sequence of BlockSpec items. A "Marketing landing" archetype might list
hero → feature-grid → testimonial → cta; a "Narrative page" archetype might listpage-header → rich-text → image-gallery → cta. Archetypes are referenced by slug from the sitemap. -
Compose navigation and routing
Primary, secondary, and footer navigation reference sitemap nodes by slug. Routing rules define URL patterns and any redirects. Both stay in sync with the sitemap because both reference the same slug graph.
-
Generate the site
A consumer reads the StructureSpec and produces pages, navigation, and routes. Each page is rendered by walking its archetype's block sequence, pulling each BlockSpec for its contract, and applying BrandSpec tokens at render time.
For client onboarding: StructureSpec turns the blank page into a guided framework. Instead of asking "what pages do you need", a content tool can present a generated sitemap with the right blocks for each page type already in place — clients fill in fields, not whole pages.
Schema structure
v0.1.0A StructureSpec document is a JSON object with a root structure key and six top-level sections. Sitemap and archetypes are the minimum viable spec; the rest are recommended for complete site definition.
structure.identity
Site name, slug, description, and version. The slug is the canonical identifier used by exports and integrations.
structure.sitemap
Recursive tree of pages. Each node carries a slug, title, archetype reference, status, and an optional children array. Nodes are referenced by slug from navigation and routing.
structure.archetypes
Reusable block sequences. Each archetype has a slug and a blocks array. Each block reference points at a BlockSpec by slug, optionally specifying variant, surface, and layout.
structure.navigation
Primary, secondary, and footer navigation structures. Items reference sitemap nodes by slug and can nest. Navigation drift is prevented because the sitemap is the source of truth.
structure.routing
URL pattern rules and redirects. Defines how sitemap slugs map to URLs, supports nested routes, and declares any source-to-target redirects to preserve from a previous structure.
structure.metadata
Administrative fields: site name, version string, last updated timestamp, and tags. Used for versioning, auditing, and tool compatibility checks.
Sitemap node fields
| Field | Type | Description | Example |
|---|---|---|---|
| slug | string | Canonical identifier for the page (kebab-case) | "about-us" |
| title | string | Human-readable page title | "About us" |
| archetype | string | Slug of the archetype that defines this page's block sequence | "narrative-page" |
| status | string | Lifecycle status: draft, planned, live, archived | "live" |
| children | node[] | Nested pages — recursive structure | [ {...}, {...} ] |
| parent | string | Optional explicit parent slug (rarely needed; tree implies it) | "company" |
Archetype block reference fields
Each item in an archetype's blocks array references a BlockSpec by slug, optionally constraining which variant, surface, or layout to use in this position.
| Field | Type | Description | Example |
|---|---|---|---|
| block | string | BlockSpec slug to use in this position | "hero" |
| variant | string | Specific BlockSpec variant slug (must exist on the referenced block) | "split" |
| surface | string | Surface attribute value to apply (must be allowed by the block's contract) | "muted" |
| layout | string | Layout attribute value to apply (must be allowed by the block's contract) | "centered" |
| required | boolean | Whether this block is required for the archetype to be valid | true |
| config | object | Optional per-instance overrides for the block | { "fields": {...} } |
Example file
JSONA condensed StructureSpec for a small marketing site with a homepage, an about page, a services landing with two child pages, and a contact page. All fields shown are part of the v0.1.0 schema.
{
"_export": {
"siteName": "Example Site",
"structureSpecVersion": "0.1.0",
"exportedAt": "2026-05-02T10:00:00.000Z"
},
"structure": {
/* ── Identity ────────────────────────────── */
"identity": {
"name": "Example Site",
"slug": "example-site",
"description": "Marketing site for a purpose-led services brand.",
"version": "1.0.0"
},
/* ── Sitemap ─────────────────────────────── */
"sitemap": [
{
"slug": "home",
"title": "Home",
"archetype": "marketing-landing",
"status": "live"
},
{
"slug": "about",
"title": "About",
"archetype": "narrative-page",
"status": "live"
},
{
"slug": "services",
"title": "Services",
"archetype": "category-landing",
"status": "live",
"children": [
{
"slug": "strategy",
"title": "Strategy",
"archetype": "service-detail",
"status": "live"
},
{
"slug": "design",
"title": "Design",
"archetype": "service-detail",
"status": "live"
}
]
},
{
"slug": "contact",
"title": "Contact",
"archetype": "contact-page",
"status": "live"
}
],
/* ── Archetypes ──────────────────────────── */
"archetypes": [
{
"slug": "marketing-landing",
"name": "Marketing landing",
"description": "Homepage and top-of-funnel pages.",
"blocks": [
{ "block": "hero", "variant": "split", "required": true },
{ "block": "feature-grid", "variant": "three-column" },
{ "block": "testimonial" },
{ "block": "cta", "variant": "centered", "surface": "accent" }
]
},
{
"slug": "narrative-page",
"name": "Narrative page",
"description": "Long-form pages — about, manifesto, story.",
"blocks": [
{ "block": "page-header", "required": true },
{ "block": "rich-text", "required": true },
{ "block": "image-gallery" },
{ "block": "cta", "variant": "inline" }
]
},
{
"slug": "category-landing",
"name": "Category landing",
"description": "Parent page introducing a group of child pages.",
"blocks": [
{ "block": "page-header", "required": true },
{ "block": "child-grid", "required": true },
{ "block": "cta" }
]
}
],
/* ── Navigation ──────────────────────────── */
"navigation": {
"primary": [
{ "slug": "about" },
{ "slug": "services", "includeChildren": true },
{ "slug": "contact" }
],
"footer": [
{ "slug": "about" },
{ "slug": "services" },
{ "slug": "contact" }
]
},
/* ── Routing ─────────────────────────────── */
"routing": {
"trailingSlash": false,
"redirects": [
{ "from": "/old-services", "to": "/services", "status": 301 }
]
},
/* ── Metadata ────────────────────────────── */
"metadata": {
"name": "Example Site",
"version": "1.0.0",
"lastUpdated": "2026-05-02T00:00:00.000Z"
}
},
"$schema": "https://structurespec.org/schema/v0.1/structurespec.json",
"version": "0.1.0"
}
Using StructureSpec
OutputStructureSpec is designed to be consumed by any tool that needs a structured site definition — page generators, CMS scaffolders, navigation builders, sitemap.xml exporters. Below are reference patterns for the most common outputs.
Generate pages from archetypes
Walk the sitemap, look up each node's archetype, and render the block sequence in order. Each block reference resolves to a BlockSpec for the contract.
// Render every page in the sitemap
const spec = await fetch('/structurespec.json').then(r => r.json());
const archetypes = new Map(
spec.structure.archetypes.map(a => [a.slug, a]).filter(Boolean)
);
function renderNode(node) {
const archetype = archetypes.get(node.archetype);
const blocks = archetype.blocks.map(renderBlock);
return { slug: node.slug, title: node.title, blocks };
}
const pages = walkSitemap(spec.structure.sitemap, renderNode);
Generate navigation from sitemap slugs
Navigation references nodes by slug, so the navigation stays in sync with the sitemap automatically. No drift, no orphan menu items.
// Build the primary navigation tree
function findNode(tree, slug) {
for (const node of tree) {
if (node.slug === slug) return node;
if (node.children) {
const hit = findNode(node.children, slug);
if (hit) return hit;
}
}
}
const primaryNav = spec.structure.navigation.primary.map(item => {
const node = findNode(spec.structure.sitemap, item.slug);
return {
label: node.title,
href: `/${node.slug}`,
children: item.includeChildren ? node.children : []
};
});
Export to sitemap.xml
The sitemap tree maps directly to the sitemaps.org XML format, with status filtering to exclude drafts and archived pages.
// Generate sitemap.xml from StructureSpec
function flattenSitemap(tree, base = '') {
return tree.flatMap(node => [
{ url: `${base}/${node.slug}`, status: node.status },
...(node.children ?? []).flatMap(c =>
flattenSitemap([c], `${base}/${node.slug}`))
]);
}
const urls = flattenSitemap(spec.structure.sitemap)
.filter(u => u.status === 'live');
For client onboarding: a generated StructureSpec turns site planning from "what pages do you need?" into "here's a sitemap with the right blocks for each page type — fill in the fields". The blank page becomes a guided framework, and the spec is a portable artefact that survives the project handoff.
Standards & references
OpenStructureSpec is designed to be standards-aware. It builds on, references, and is interoperable with several established frameworks. It is not a replacement for any of them — it is a structured layer that makes them composable in a single, machine-readable file.
BlockSpec
The sibling open standard for content blocks. StructureSpec consumes BlockSpec — every block reference in an archetype points at a BlockSpec by slug, optionally constraining the variant, surface, or layout. BlockSpec describes the parts; StructureSpec describes the wholes.
BrandSpec
The sibling open standard for organisational brand definitions. BrandSpec tokens are applied at render time — the same StructureSpec produces visually different sites when paired with different BrandSpecs, without any structural change.
JSON Schema
The StructureSpec document format is defined using JSON Schema (Draft 2020-12). The $schema field in every StructureSpec file points to the published schema, enabling validation in any compatible tool. Editors such as VS Code will auto-complete and validate a StructureSpec file when the schema URI is present.
Sitemap protocol
The StructureSpec sitemap maps directly to the sitemaps.org XML protocol used by search engines. A StructureSpec consumer can produce a valid sitemap.xml by walking the sitemap tree and filtering by status.
Schema.org WebPage
StructureSpec page archetypes can be annotated with Schema.org WebPage structured data. Each archetype declares the page type it represents, enabling structured-data export at render time.
HTTP status codes
The routing object's redirects array uses standard HTTP status codes (RFC 9110) — 301 for permanent, 302 for temporary, 308 for permanent with method preservation. Consumers translate these to whatever the deployment target supports.
Composition with BlockSpec: StructureSpec and BlockSpec are designed as a pair. BlockSpec defines individual blocks as complete units (contract + fields + guidance). StructureSpec composes them into pages and sites. Together they replace what wireframe libraries, sitemap diagrams, and CMS field configurations each cover separately.