Page anatomy
Frontmatter, body, and the conventions Tangly expects on every page.
~ 3 min read
Page anatomy
A Tangly page is an .mdx file with YAML frontmatter at the top and MDX body underneath. That’s the whole structure.
---
title: Page title
description: One-line description for search results and OG tags.
icon: book
---
The page body. Markdown. MDX components. JSX expressions if you need them.
## Sections
Headings auto-generate ids; link to them as `/page#sections`.Frontmatter
The YAML block at the top. Parsed by gray-matter, validated against the frontmatter schema.
Minimum
Most pages only need two fields:
---
title: Quickstart
description: 60-second tour.
---Common
| Field | When to use |
|---|---|
title | Always. Renders as page H1, sidebar entry, browser tab, OG title. |
description | Always. Subtitle below H1, meta description, OG description. |
icon | If the page is in a Card on a landing page or in a sidebar entry. |
sidebarTitle | When title is too long for the sidebar (e.g. title: "Authentication and authorization", sidebarTitle: "Auth"). |
tag | Beta / new / deprecated chip on the sidebar entry. |
draft | While drafting. Hidden in production builds. |
noindex | When the page shouldn’t appear in search engines or llms.txt. |
mode | When the page needs an unusual layout (wide, center, custom). |
For the full list, see Frontmatter.
The body
Standard CommonMark + GFM extensions + JSX components. See Markdown & MDX for the full reference.
Don’t write your own H1
The page H1 renders automatically from the title frontmatter field. Don’t add a # Title line (or <h1>) at the top of the body; you’ll get two H1s.
---
title: Quickstart
---
This is the first paragraph. No `# Quickstart` line above it.tangly dev warns in the terminal when it finds an H1 in content so you can catch this while authoring.
Use H2 for sections
Top-level sections under the page H1 should be ## H2. The right-rail TOC indexes H2 and H3 only. Skip levels and you’ll confuse the TOC.
Component conventions
Built-in MDX components are auto-injected. No imports.
<Note>This shows up everywhere. No import needed.</Note>For custom components, drop them in theme/ at your project root and reference them by name. See Custom components.
Linking
Internal links use absolute slugs without .mdx:
See [Quickstart](/quickstart) for the 60-second tour.
See [API auth](/reference/schema#auth-methods) for headers.tangly check validates internal links at build time.
External links open in new tabs automatically:
[Astro](https://astro.build)Images
Drop them in images/ (or static/, public/, assets/). Reference by absolute path:
Every image gets a lightbox on click. To opt out, see <LightboxImage>.
Section headings + anchors
Every heading auto-generates a slug-style id:
## Rate limits <!-- id="rate-limits" -->
## Things & stuff <!-- id="things-stuff" -->For stable ids that survive heading renames, pin them:
## Rate limits {#rate-limits}Where pages live
The slug is the path from the project root, no .mdx:
| File path | Slug | URL |
|---|---|---|
introduction.mdx | introduction | /introduction |
guides/getting-started.mdx | guides/getting-started | /guides/getting-started |
reference/cli/dev.mdx | reference/cli/dev | /reference/cli/dev |
The slug is what you reference in docs.json#navigation and what you link from other pages.
The home page
A root index.mdx (or index.md) is the site home and renders at /, the same as Mintlify. It doesn’t need to be listed in docs.json#navigation; when present it takes over the root URL and inherits the first tab’s sidebar. With no root index page, / shows a brief loading splash that redirects to the first navigable page.
A nested foo/index.mdx collapses to the slug foo (served at /foo).
Files that aren’t pages
Some files are never treated as docs pages, matching Mintlify:
| Excluded | Why |
|---|---|
README.md, LICENSE.md, CHANGELOG.md, CONTRIBUTING.md | Project meta, auto-ignored |
_*.mdx / _*.md | Leading underscore marks partials (e.g. _section.mdx) |
snippets/, components/, templates/, public/, static/, assets/ (at the project root) | Reserved directories |
AGENTS.md is rendered as a page (Mintlify renders it too). .tanglyignore controls the static-asset copy step at build time, not page discovery.
Validation
tangly check runs frontmatter validation against the schema, walks every internal link, and confirms every navigation entry resolves to a real file. Run it before committing:
bunx tangly checkFor strict mode (warnings become errors):
bunx tangly check --strictWhat goes where
Coming from Mintlify, the conventions here will feel familiar; Tangly mostly inherits them. The exceptions:
- Tangly auto-renders the H1 from
title. Don’t repeat it in the body. - Internal links are absolute slugs; no
.mdxextension. - Images live under recognized roots (
images/,static/,public/,assets/). - Frontmatter is non-fatal; invalid fields warn, don’t fail.
For the full delta, see Migration → Compatibility.