Format & agent instructions
Paste this to an agent (or give it the link /info.md) and ask for a
sitemap of a site. It answers with a #gz= link that opens the map in one click
(when it can run code), plus the JSON. No link? Copy its reply and paste it on the homepage: the map opens straight away.
# Sitemap JSON format (version 1)
You are asked to describe a website's structure as a sitemap JSON, following the format below. It's viewed at https://sitemaps.lucabunino.com as an interactive map.
**Share it as a `#gz=` link first** (how: see "Delivering it"), then the JSON as a fallback.
## Delivering it
**Preferred: a `#gz=` link.** It opens the map in one click, with the whole sitemap packed inside the link (after `#`); nothing is uploaded or stored on a server. Give it whenever you can run code (Python, JavaScript or a shell), **at the top of your reply**:
```python
import base64, gzip, json
data = {...} # the sitemap object
packed = base64.urlsafe_b64encode(gzip.compress(json.dumps(data).encode())).decode().rstrip("=")
print("https://sitemaps.lucabunino.com/#gz=" + packed)
```
```js
const data = { /* the sitemap object */ }
const gz = await new Response(new Blob([JSON.stringify(data)]).stream().pipeThrough(new CompressionStream('gzip'))).arrayBuffer()
const packed = btoa(String.fromCharCode(...new Uint8Array(gz))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
console.log('https://sitemaps.lucabunino.com/#gz=' + packed)
```
```sh
gzip -c sitemap.json | base64 | tr '+/' '-_' | tr -d '=\n' | sed 's|^|https://sitemaps.lucabunino.com/#gz=|'
```
Run the code and paste the link it prints; never type or edit the packed part by hand (one wrong character breaks it). Same for maps you change later: send a fresh `#gz=` link each time.
**Then, as a fallback, the JSON** in a single ```json code block below the link. If the link can't be made (no way to run code), this is the delivery: the person copies your reply (all of it is fine) and pastes it on https://sitemaps.lucabunino.com, which finds the JSON and opens the map.
Other options, only if asked: `#json=` + base64url of the plain JSON (no gzip), or a `.json` file to drop on the page.
## Top level
```json
{
"version": 1,
"title": "Project — Sitemap",
"subtitle": "Site structure and links between pages",
"lang": "en",
"defaultMode": "full",
"categories": [ ... ],
"cards": [ ... ],
"footnote": "optional text under the map"
}
```
- `title` (required), `subtitle`, `footnote`: plain text.
- `lang`: language the content is written in (`"en"`, `"it"`…).
- `defaultMode`: `"structure"` (titles only), `"full"` (everything) or `"outline"` (text document).
## Categories
Legend entries; cards reference them by id and take their color.
```json
{ "id": "main", "label": "Main section", "color": "#FFE94D" }
```
- `id`: lowercase, digits and dashes (`main`, `content-template`).
- `color`: 6-digit hex. Light, saturated colors work best (dark text sits on them).
## Cards
One card per page or page template.
```json
{
"id": "explore",
"title": "Explore",
"note": "small text next to the title",
"category": "main",
"parents": ["home"],
"label": "caption above the card, e.g. reachable from footer",
"itemsLayout": "stack",
"items": [ ... ]
}
```
- `id` (required, unique) and `title` (required).
- `parents`: ids of the cards this one hangs from. **The layout is computed from this**:
- the first card with no parents is the root, alone on the top row;
- each child of the root gets its own column, in array order;
- deeper cards sit under their parents, spanning from the leftmost to the rightmost parent;
- other cards without parents float in the last column, without lines (use `label` to say how they're reached).
- `itemsLayout`: `"stack"` (default) or `"row"` (items side by side; good for the homepage's blocks).
- `col`, `span`, `row`: optional overrides of the computed position, 1-based (root is row 1, col 1). Rarely needed.
## Items
What's on the page, top to bottom. Items nest through `children`.
```json
{
"kind": "item",
"title": "bold part",
"text": "regular text",
"note": "(muted text)",
"url": "/editions/[slug]",
"links": [{ "to": "content", "label": "Content page" }],
"emphasis": false,
"open": true,
"children": [ ... ]
}
```
| kind | renders as |
|---|---|
| `item` | boxed row (default) |
| `block` | kicker (`title`) + text; use inside `itemsLayout: "row"` cards |
| `chips` | titled group; `children` are `chip` items |
| `chip` | small tag |
| `variants` | inline list of chips (`children`), with `title` as label |
| `accordion` | collapsible group; `children` shown when `open` |
| `numbered` | auto-numbered among its siblings; `children` shown when `open` |
| `columns` | side-by-side `column` children |
| `column` | one column: optional `title`, then `children` |
| `list` | indented `children` |
| `note` | muted text |
- `links[].to`: a card id. Shown as a pill in the target card's color; clicking flies to it.
- `links[].href`: an external URL instead.
- `url`: URL pattern, shown muted.
- `emphasis`: highlight this item.
## Rules
- Every `parents` entry and every `links[].to` must be an existing card id.
- Keep text short: these are labels, not paragraphs.
- No `_id`, `_key` or `_type` needed; they're ignored.
- Valid JSON only: double quotes, no comments, no trailing commas.
## Minimal example
```json
{
"version": 1,
"title": "Bakery — Sitemap",
"categories": [
{ "id": "main", "label": "Main", "color": "#FFE94D" },
{ "id": "template", "label": "Template", "color": "#7FE05F" }
],
"cards": [
{
"id": "home",
"title": "Home",
"category": "main",
"itemsLayout": "row",
"items": [
{ "kind": "block", "title": "Hero", "text": "seasonal cake" },
{ "kind": "block", "title": "Shop", "links": [{ "to": "shop" }] }
]
},
{
"id": "shop",
"title": "Shop",
"category": "main",
"parents": ["home"],
"items": [{ "kind": "item", "text": "Product grid", "links": [{ "to": "product" }] }]
},
{
"id": "product",
"title": "Product",
"category": "template",
"parents": ["shop"],
"items": [
{ "kind": "item", "text": "Photos" },
{ "kind": "item", "text": "Add to cart" }
]
}
]
}
```
A fuller example: https://sitemaps.lucabunino.com/example.json