Skip to content

Content map

Orbit reads an Astro site’s content config, so an Astro site needs no setup. Any other site — Gatsby, Next.js, Nuxt, Hugo, Eleventy, Jekyll — tells Orbit where its content is with a content map: a sections: list in orbit.config.yaml, at the root of the site.

If your content is Markdown (or MDX) files in the repository, rendered by your templates, that’s all Orbit needs.

orbit.config.yaml
sections:
posts:
files: content/blog/**/index.md # where the pages are
newPage: "{slug}/index.md" # where a new one goes
template: src/templates/blog-post.js # what renders them
fields: schemas/post.schema.json # the form (optional)
home:
files: content/pages/home.md # one fixed page

Each entry is a section in Orbit’s sidebar, named by its key.

KeyWhat it saysNeeded?
filesThe pages, as a path from the site’s root — a pattern (content/blog/*.md, posts/**/*.mdx) or one file for a fixed page. It must start in a folder.Yes
templateThe file that renders these pages: a Gatsby template, a Next.js route (app/blog/[slug]/page.tsx), a Hugo layout.To let editors add pages
newPageWhere a new page goes, from the folder files starts in, with {slug} for its name. Default: {slug} plus the pages’ extension. Use {slug}/index.md when each page has its own folder.No
fieldsThe form’s fields — see below.No

Editors can add pages to a section only when it names a template and that file is in the site. It’s your word that a new file there becomes a page — a folder of notes or drafts that nothing renders shouldn’t take new pages.

  • No template — a fixed page or a fixed set of pages: editors edit them, but can’t add, delete or move them.
  • Template renamed or deleted — the section goes back to edit only, and Site settings ▸ What Orbit edits says why.

No collection rule can switch adding on without a template. The rules still narrow it — which folders take new pages, read-only, no body.

There are three ways to give a section its form:

  1. Leave fields out. Orbit works the fields out from the section’s pages: every field any page uses, in the order the first page writes them, each optional. The kind of value sets the type — text, a number, true/false, a list, a group, or an image (a path ending .jpg, .png, …). Fields whose pages disagree are shown as plain text. Dates stay as text so their format is never changed — list a field as date to get a date picker.

  2. List them, when you want required fields, dropdowns or date pickers:

    sections:
    team:
    files: content/team/*.md
    template: src/templates/person.js
    fields:
    - { name: name, required: true }
    - { name: role, type: enum, options: [barista, roaster, manager] }
    - { name: started, type: date }
    - { name: photo, type: image }
    - name: links
    type: array
    items:
    type: object
    fields: [{ name: label }, { name: href }]

    Types: string (the default), number, boolean, date, enum (with options), image, array (with items), object (with fields). Fields are optional unless required: true.

  3. Point at a JSON Schema file: fields: schemas/post.schema.json. It’s an object whose properties are the fields, in order; required lists the required ones. "format": "date" or "date-time" gives a date field, "format": "image" an image picker, and enum a dropdown. ($ref and allOf aren’t followed yet.)

When you list fields (2 or 3), a field a page has that isn’t in the list is shown in the form but locked, with the reason — you haven’t said what it is, so Orbit keeps it exactly as written. What Orbit edits lists these, so you can add them.

Set assetsDir to the folder images live in. How Orbit writes a reference depends on where that folder is:

  • The folder the site serves from its root — public/ (Astro, Next.js) or static/ (Gatsby, Hugo): images are referenced from the root, as /images/photo.jpg.
  • Anywhere else (src/images): references are relative to the page, as your build expects for processed images.
  • Pages with their own folder (newPage: "{slug}/index.md"): an image uploaded for the page goes into that folder, as ./photo.jpg.

A content-map site gets the same Orbit as an Astro one:

FeatureOn a content-map site
The form and checks before savingFrom the section’s fields — listed, a JSON Schema, or inferred
Folders, new pages, moving, deletingThe same; adding (and so moving and deleting) needs the template
Images, picker and uploadassetsDir; root-served images from public/ or static/; a page’s own folder
MDX pages and componentsWith the generator’s MDX package (gatsby-plugin-mdx, @next/mdx, next-mdx-remote)
Snippets ([[name]])In snippets/ at the root, or snippets.dir
Data filesdata: — JSON and YAML
Preview, accessibility tipsThe same
Publishing, history, undo, conflictsThe same — it’s all git
Site iconFound in public/, static/ or Next’s app/, or set site.favicon

Only Astro’s site pages (Markdown in src/pages) are Astro-only — elsewhere, add those pages to the map as a section.

Ask Claude, ChatGPT, Gemini or Cursor to “read orbitmarkdown.com/llms.txt and make my site Orbitable” — Orbit publishes a guide written for assistants. See Set up with AI.

Open the site in Orbit and go to Site settings ▸ What Orbit edits (developers only). It lists each section with its page count and whether editors can add pages, plus:

  • folders of Markdown that no section covers — content the map may have missed (read-mes and licences don’t count);
  • fields pages use that the section’s list leaves out.

Mistakes in the map itself — a missing files, a newPage without {slug}, an unknown field type — show at the top of Site settings with their line numbers.

  • TOML or JSON front matter (+++, Hugo’s alternatives) — only YAML (---).
  • File names with a date in front (Jekyll’s 2026-10-07-my-post.md) for new pages — editing existing ones works.
  • Moving a page that has its own folder to another folder (its images would be left behind).
  • Editing the map in Site settings — edit orbit.config.yaml itself.
  • Content in a headless CMS or a database — it isn’t in the repository.