Getting Started
Add static React documentation with Ardo, either through an agent-guided adoption or a small standalone project.
For an existing repository, start with Adopt Ardo in an Existing Project. It gives a coding agent a safe, reference-project-based path without replacing your application setup. The standalone CLI remains useful for an empty directory when its default shape is already what you want.
Existing project
Give your coding agent the URL https://ardo-docs.dev/llms.txt and the adoption guide. It will inspect the repository, select the closest reference project, and propose the smallest change before editing files.
Prerequisites
You'll need:
Empty-directory convenience
Use create-ardo only when you want its opinionated, complete starter shape — configuration, example content, and a GitHub Pages workflow — in a new empty directory.
pnpm create ardo@latest my-docs
cd my-docs
pnpm install
pnpm devOpen http://localhost:5173 and you'll see your site. Add an MDX file to app/routes/, and Ardo includes it in the generated navigation.
Manual Installation
If you want to add Ardo to an existing workspace or understand the scaffold, follow the manual setup. The split is simple: Vite handles build-time configuration, React handles UI configuration.
1. Create a new project
mkdir my-docs
cd my-docs
pnpm init2. Install dependencies
pnpm add ardo lucide-react react react-dom react-router isbot
pnpm add -D @react-router/dev @tailwindcss/vite tailwindcss typescript vite @types/react @types/react-dom3. Add package scripts
React Router owns the dev server, production build, and local preview commands:
{
"scripts": {
"dev": "react-router dev",
"build": "react-router build",
"preview": "vite preview"
}
}When you use pnpm, add the same build-script allowlist that the scaffold ships so esbuild can prepare Vite's native dependency:
# pnpm-workspace.yaml
packages:
- "."
allowBuilds:
esbuild: true4. Create Vite configuration
The ardo() plugin handles build-time configuration. UI configuration (navigation, sidebar, footer) is done via JSX props in root.tsx:
import { defineConfig } from "vite"
import tailwindcss from "@tailwindcss/vite"
import { ardo } from "ardo/vite"
export default defineConfig({
plugins: [
tailwindcss(),
ardo({
title: "My Documentation",
description: "My awesome documentation site",
}),
],
})5. Create React Router configuration
Ardo uses React Router 8 under the hood. For a static documentation site, you want pre-rendering enabled and SSR off:
import type { Config } from "@react-router/dev/config"
export default {
ssr: false,
prerender: true,
} satisfies Config6. Create app files
These are standard React Router entry files plus Ardo's root component. If you've worked with React Router before, the shape should feel familiar.
app/root.tsx:
import {
ArdoGeneratedSidebar,
ArdoHeader,
ArdoNav,
ArdoNavLink,
ArdoRoot,
ArdoRootLayout,
ArdoSidebar,
ArdoSidebarSection,
} from "ardo/ui"
import config from "virtual:ardo/config"
import "./app.css"
import "ardo/ui/styles.css"
export function Layout({ children }: { children: React.ReactNode }) {
return <ArdoRootLayout>{children}</ArdoRootLayout>
}
export default function Root() {
return (
<ArdoRoot config={config}>
<ArdoHeader>
<ArdoNav>
<ArdoNavLink to="/guide/getting-started">Guide</ArdoNavLink>
</ArdoNav>
</ArdoHeader>
<ArdoSidebar>
<ArdoSidebarSection id="guide" label="Guide" to="/guide/getting-started">
<ArdoGeneratedSidebar section="guide" />
</ArdoSidebarSection>
</ArdoSidebar>
</ArdoRoot>
)
}app/app.css:
@layer theme, base, components, utilities;
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/utilities.css" layer(utilities);app/entry.client.tsx:
import { startTransition, StrictMode } from "react"
import { hydrateRoot } from "react-dom/client"
import { HydratedRouter } from "react-router/dom"
startTransition(() => {
hydrateRoot(
document,
<StrictMode>
<HydratedRouter />
</StrictMode>
)
})app/entry.server.tsx:
import type { EntryContext } from "react-router"
import { ServerRouter } from "react-router"
import { renderToReadableStream } from "react-dom/server"
import { isbot } from "isbot"
export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
routerContext: EntryContext
) {
const userAgent = request.headers.get("user-agent")
const stream = await renderToReadableStream(
<ServerRouter context={routerContext} url={request.url} />,
{
onError(error: unknown) {
console.error(error)
responseStatusCode = 500
},
}
)
if (userAgent && isbot(userAgent)) {
await stream.allReady
}
responseHeaders.set("Content-Type", "text/html")
return new Response(stream, {
status: responseStatusCode,
headers: responseHeaders,
})
}7. Create your first document
Create app/routes/guide/getting-started.mdx:
---
title: Getting Started
---
# Getting Started
Welcome to your documentation site!That's it. Run pnpm dev and you've got a documentation site.
The create-ardo CLI generates all of these files automatically — use it when you want to skip
the boilerplate and get straight to writing.
Development
Start the development server:
pnpm devYour site will be running at http://localhost:5173. Changes to MDX and TSX routes flow through Vite's development server.
Production Build
When you're ready to publish:
pnpm buildThe output lands in build/client/ — a fully static site ready for any hosting platform. Preview it locally before deploying:
pnpm previewProject Structure
Here's what an Ardo project looks like. If you've worked with React Router, the layout will feel natural:
my-docs/
├── app/
│ ├── routes/ # Your MDX/MD content files
│ │ ├── guide/
│ │ │ └── getting-started.mdx
│ │ └── home.tsx # Home page
│ ├── root.tsx # Root layout
│ ├── entry.client.tsx # Client entry
│ ├── entry.server.tsx # Server entry
│ └── app.css # Tailwind v4 utility layers
├── vite.config.ts # Vite + Ardo configuration
├── react-router.config.ts # React Router configuration
├── pnpm-workspace.yaml # pnpm build-script allowlist, when using pnpm
├── tsconfig.json
└── package.json
The repository also includes runnable examples for common layouts:
basic,
library, and
monorepo. For Markdown
owned outside app/routes/, start with the
content sources reference.
Next Steps
Your site is running. Now make it yours:
- Write richer content with Markdown Features
- Style your pages with Tailwind CSS — included by default, ready to use
- Customize the look with Custom Theme
- Style with type-safe tokens using Vanilla Extract —
.css.tsfiles work out of the box - Deploy your site to GitHub Pages, Netlify, or Vercel
- Explore the API Reference