Example: a documentation repository structure
Layout
Section titled “Layout”docs-repo/├── src/│ ├── content/│ │ ├── en/│ │ │ ├── getting-started/│ │ │ │ ├── index.md│ │ │ │ ├── installation.md│ │ │ │ └── first-project.md│ │ │ ├── guides/│ │ │ │ └── ...│ │ │ └── reference/│ │ │ └── ...│ │ └── fr/│ │ └── <mirrors the en/ tree>│ ├── components/ # reusable page components│ └── assets/ # images referenced from content├── scripts/ # build-time automation (redirects, search index, etc.)├── tests/ # automated checks on the built output├── config-file # site/build configuration└── package-manifestWhy this shape
Section titled “Why this shape”- Locale is the top-level split, not a suffix on each filename (
installation.md/installation.fr.md). This keeps each language a complete, independently navigable tree - see translation on why language-first organization simplifies branching for parallel translation work. - Content is grouped by reader intent (
getting-started/,guides/,reference/), not by internal team structure or by which product team owns a page. Readers navigate by what they’re trying to do, not by your org chart. scripts/andtests/are separated fromcontent/. A contributor fixing a typo never needs to look at build tooling, and a contributor changing the build never touches prose by accident.- Assets live near the content tree, not in a single flat
images/folder with thousands of files - makes it obvious which images are still referenced when a page is deleted.
What doesn’t belong in this repository
Section titled “What doesn’t belong in this repository”- Generated output (built HTML, PDFs) - regenerate it in CI, don’t commit it. A
.gitignoreentry, not a folder, is the right home for build artifacts. - Secrets or credentials for any service the build touches (analytics keys, deploy tokens) - those belong in the CI/CD platform’s secret store, never in tracked files.
- Binary source files (see source format) - if a legacy asset must ship as binary, keep it small and treat it as an exception, not a pattern to repeat.