Project structure
Files and folders in a Pinnate docs project synced from git.
This page describes the usual layout of a docs-as-code project that Pinnate imports from GitHub or GitLab. You choose the sync root on the site’s Integrations page; everything below is relative to that root.
Recommended layout
docs/ # sync root (name is yours)
├── site.yaml # site title, theme, sections, excludes
├── introduction.md # guide pages (any .md / .mdx)
├── get-started/
│ ├── quickstart.md
│ └── project-structure.md
├── assets/ # images referenced from Markdown (optional)
│ └── logo.svg
└── openapi/ # often outside this root — see below
└── openapi.yaml
Only the site sync root needs site.yaml and Markdown. OpenAPI for the registry usually lives in a separate path (or another repo) attached to the API resource, not necessarily next to the docs.
Reserved and special files
Path | Role |
|---|---|
| Site metadata and top-nav |
| Guide pages discovered under each guide section’s |
Paths in | Skipped during discovery (for example |
There is no required folder name for pages or assets. Subfolders under a guide path become sidebar groups.
site.yaml
site.yaml is the control plane for a git-backed site when sections: is present:
Site title, visibility, theme, navbar links
Top-nav structure (guides, embeds, groups)
Global and per-section exclude globs
Only Markdown under a declared guide path (minus excludes) is imported. Files outside those paths are ignored for that section.
Full field docs: Site settings and site.yaml reference.
Minimal example
title: Acme Docs
visibility: public
theme:
accent_color: '#0F766E'
layout: centered
exclude:
- README.md
sections:
- name: Guide
slug: guide
path: .
- name: API
slug: api
api: payments
Guide pages
Each Markdown file becomes one page. Nested directories map to nested sidebar folders and to path-based URL slugs:
File (under a guide section | Default public URL |
|---|---|
|
|
|
|
Override the leaf or path with frontmatter slug. Slugs must be unique within the section. See Page settings.
You do not have to list every file in YAML. Prefer folder discovery plus position in frontmatter. Use an explicit pages: list only when you need a pinned order that discovery cannot express.
Assets
Reference images with relative paths from the Markdown file:

Site chrome assets (logo, dark logo, favicon) use absolute HTTPS URLs in theme — see Theme. Host those files on your CDN or object storage.
Guide-page binaries can live under an assets/ folder in the docs repo; sync behavior for non-Markdown files depends on your git provider. First-class upload/CDN mirroring of repo assets is not required when you already host URLs yourself.
OpenAPI and generators
Registry OpenAPI is not required inside the docs root:
Resource | Typical sync path | Config |
|---|---|---|
Site |
|
|
API |
| API Integrations → file path |
Schema / ruleset |
| Per-resource Integrations |
Same monorepo is fine: attach different paths on each resource. See Registry git sync and Site git sync.
What sync ignores
Files outside the configured sync root
Paths matching site or section
excludeglobsNon-Markdown files for guide sections (they are not turned into pages)
Without
sections:insite.yaml, only the guide section is rebuilt from Markdown; existing embed sections are left alone
Multi-repo publishing
Coming soon — Publish one hostname from multiple independent repositories (multi-source). Today, use one docs repo (or monorepo paths) per site, and separate remotes per API/schema/ruleset as needed.