Getting Started
Project Structure
Learn about the project structure of Docora.
Global structure
Docora is a Next.js theme package that extends a standard App Router application with documentation features. This gives you the flexibility of a full Next.js project.
When you create a new Docora project with npx create-docora my-docs, you get:
my-docs/
├── content/ # Your markdown content
│ ├── index.mdx # Homepage
│ └── docs/ # Documentation pages
├── app/ # Next.js App Router
│ ├── [[...slug]]/ # Catch-all that compiles content
│ ├── layout.tsx # Root layout
│ └── globals.css # Theme stylesheet
├── lib/source.ts # Content source
├── docs.config.ts # Site configuration
├── next.config.ts # Next.js configuration
└── package.json # Dependencies and scriptsYou can still use any feature or file of a classical Next.js project:
my-docs/
├── app/
│ ├── components/ # Components (add your own)
│ ├── about/page.tsx # Extra pages (alongside the catch-all)
│ └── api/ # API routes
├── middleware.ts # Route middleware
└── public/ # Static assetscontent/ directory
This is where you write pages in Markdown and MDX. Docora automatically generates routes based on your file structure — there are no page files to write.
Single language structure:
content/
├── index.mdx # Landing page (/)
├── docs/
│ ├── index.mdx # Documentation index (/docs)
│ └── 1.getting-started/
│ ├── .navigation.yml # Section title and icon
│ ├── 1.introduction.mdx # /docs/getting-started/introduction
│ └── 2.installation.mdx # /docs/getting-started/installation
└── guide/
└── configuration.mdx # /guide/configurationA file's path becomes its route, minus the extension:
| File | Route |
|---|---|
content/index.mdx | / |
content/docs/index.mdx | /docs |
content/docs/1.getting-started/1.installation.mdx | /docs/getting-started/installation |
Put documentation under a docs/ subfolder to serve it at /docs, which
keeps / free for a landing page. You can also add ordinary App Router pages
alongside the catch-all if you need a custom React route.
Multi-language structure (with i18n):
content/
├── en/
│ ├── index.mdx # English landing page (/en)
│ └── docs/
│ └── 1.getting-started/
│ └── 1.introduction.mdx # /en/docs/getting-started/introduction
└── fr/
├── index.mdx # French landing page (/fr)
└── docs/
└── 1.getting-started/
└── 1.introduction.mdx # /fr/docs/getting-started/introductionScaffold this layout with the i18n template:
npx create-docora my-docs -t i18nThe i18n starter prefixes every route with a locale and builds a separate sidebar for each language. See Installation for how to create one.
Ordering
A numeric prefix sets the position in the sidebar and is stripped from the
route. 1.installation.mdx sorts before 2.project-structure.mdx and is
served at /docs/getting-started/installation.
Files without a prefix sort after the numbered ones, alphabetically.
Sections
A folder becomes a sidebar section. Give it a title and an icon with a
.navigation.yml beside its pages:
title: Getting Started
icon: rocketWithout one, the folder name is humanised — getting-started becomes
Getting Started.
Hiding pages
Anything set in a document's frontmatter overrides the conventions above.
Set navigation: false to keep a page routable but out of the sidebar, or pass
an object to change how it appears:
---
title: A very long page title
navigation:
title: Short title
icon: flag
---The landing page
content/index.mdx is the site root. Give it layout: landing and it renders
without the sidebar and table of contents.
public/ directory
Files in public/ are served at the root and are not modified by the build
process. This is where you put images, icons, and other static assets — for
example public/images/banner.png is available at /images/banner.png.
package.json
This file contains the dependencies and scripts for your application. The
package.json of a Docora application is minimal and looks like:
{
"name": "my-docs",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"docora": "latest",
"next": "^16.3.1",
"react": "^19.2.0",
"react-dom": "^19.2.0"
}
}next.config.ts
Wrap your Next.js config with withDocora so the theme is transpiled and the
content directory is traced into the build:
import { withDocora } from 'docora/next'
export default withDocora({})You can still pass any Next.js option through:
import { withDocora } from 'docora/next'
export default withDocora({
images: {
remotePatterns: [{ hostname: 'res.cloudinary.com' }],
},
})docs.config.ts
This is where you configure Docora to fit your branding, handle SEO, set your locale, and adapt links and socials.
import { defineDocsConfig } from 'docora'
export default defineDocsConfig({
site: {
name: 'My Docs',
description: 'My awesome documentation',
locale: 'en',
},
header: {
links: [{ label: 'Docs', href: '/docs/getting-started/introduction' }],
},
// ... other configurations
})Pass the result to DocsRoot in app/layout.tsx.
Full Next.js Project Capabilities
Since Docora is a theme on top of the App Router, you can use any feature of a standard Next.js project:
my-docs/
├── app/ # App Router
│ ├── layout.tsx # Root layout (wraps DocsRoot)
│ ├── [[...slug]]/ # Content catch-all
│ ├── globals.css # Custom theme
│ ├── about/page.tsx # Custom pages (outside of content)
│ ├── components/ # Custom React components
│ └── api/ # API routes
├── middleware.ts # Route middleware
├── public/ # Static assets
└── next.config.ts # Next.js configurationThe catch-all at app/[[...slug]]/page.tsx compiles whichever document matches
the URL. More specific App Router pages — app/about/page.tsx, API routes, and
the like — take precedence over it.
Recolour tokens and swap the font on the Theme page, or swap layout slots without leaving the Next.js app.