A modern, Stripe-grade documentation site for Auths built with Next.js, Markdoc, and Tailwind CSS.
- Clean content separation: Markdown source files in
content/docs/, rendered via Markdoc - Responsive 3-column layout: Persistent sidebar navigation, sticky top bar, "On This Page" TOC
- Syntax highlighting: Code blocks rendered with Prism React Renderer
- Auto-generated heading IDs: Smooth scroll anchors with GitHub-compatible slug generation
- Mobile-friendly: Slide-in drawer navigation for screens under 1024px
- Static pre-rendering: Catch-all routes for placeholder pages
- bun
>=1.0.0(install bun) - Node.js
>=18.0.0
bun installbun run devOpen http://localhost:3000 in your browser. The site will auto-reload when you edit files.
bun run buildbun startauths-docs/
├── app/ # Next.js app directory
│ ├── docs/
│ │ ├── layout.tsx # 3-column grid layout
│ │ ├── page.tsx # Docs landing page
│ │ ├── [topic]/page.tsx # Dynamic guide pages
│ │ ├── concepts/[topic]/page.tsx # Placeholder concept routes
│ │ └── reference/[topic]/page.tsx # Placeholder reference routes
│ ├── globals.css # Global styles + smooth scroll
│ └── layout.tsx # Root layout
├── components/
│ ├── docs/ # Docs-specific components
│ │ ├── DocsTopBar.tsx
│ │ ├── DocsSidebar.tsx
│ │ ├── DocsMobileDrawer.tsx
│ │ ├── OnThisPage.tsx
│ │ ├── DocsPrevNext.tsx
│ │ └── DocWrapper.tsx
│ ├── markdoc/ # Markdoc-specific components
│ │ ├── Callout.tsx
│ │ └── CodeFence.tsx
│ └── CodeBlock.tsx # Prism React Renderer wrapper
├── content/
│ └── docs/ # Markdown source files
│ ├── sign-commits.md
│ ├── installation.md
│ ├── concepts/
│ └── reference/
├── lib/
│ ├── docs-navigation.ts # Nav data + prev/next utilities
│ ├── markdoc.ts # Parse + transform Markdoc
│ └── toc-context.tsx # TOC state context
├── markdoc/
│ ├── tags/
│ │ └── callout.ts # {% callout %} tag schema
│ └── nodes/
│ ├── heading.ts # Auto-generate heading IDs
│ └── fence.ts # Code block override
├── package.json
├── tsconfig.json
├── next.config.ts
├── tailwind.config.ts
└── README.md # This file
-
Create a Markdown file in
content/docs/--- title: "Page Title" description: "Short description for metadata" --- ## Section Heading Content here. Code blocks are automatically syntax-highlighted. ```bash auths sign-commit --help
More content...
-
Add a route file in
app/docs/<slug>/page.tsximport fs from 'fs' import path from 'path' import { parseDoc } from '@/lib/markdoc' import Markdoc from '@markdoc/markdoc' import React from 'react' import { TocSetter } from '@/lib/toc-context' import { DocWrapper } from '@/components/docs/DocWrapper' export default async function Page() { const source = fs.readFileSync( path.join(process.cwd(), 'content/docs/<slug>.md'), 'utf8' ) const { content, frontmatter, toc } = parseDoc(source) const rendered = Markdoc.renderers.react(content, React) return ( <> <TocSetter toc={toc} /> <DocWrapper>{rendered}</DocWrapper> </> ) } export async function generateMetadata() { // Generate SEO metadata from frontmatter }
-
Update
lib/docs-navigation.tsto add the new page to the sidebar
Use standard fenced code blocks with language specifier:
```typescript
const greeting = 'Hello, Auths!'
console.log(greeting)
```Supported languages: bash, typescript, javascript, json, yaml, python, go, rust, and more via Prism.
Use the {% callout %} tag:
{% callout type="info" title="Pro Tip" %}
This is a callout box. Use `type="warning"` or `type="error"` for different styles.
{% endcallout %}Headings automatically generate IDs for smooth scrolling:
## This becomes an anchor
You can link to it with `[link](#this-becomes-an-anchor)`.
The ID is generated from the heading text using GitHub-compatible slug rules.| Command | Description |
|---|---|
bun run dev |
Start dev server at http://localhost:3000 |
bun run build |
Build for production |
bun start |
Start production server (requires build) |
bun run lint |
Run ESLint |
bun run type-check |
Run TypeScript type checker |
Instead of using the @markdoc/next.js webpack plugin, pages are Server Components that call parseDoc() to render Markdown. This gives fine-grained control over the route structure and avoids Turbopack complications.
The Markdoc heading node override uses github-slugger to generate URL-safe IDs from heading text. This enables smooth scroll navigation without manual id attributes. The generated IDs match GitHub's slug format (handles punctuation, unicode, etc.).
Instead of querying the DOM on client mount (which causes layout shifts and hydration mismatches), the server extracts the TOC from the Markdoc AST and passes it via React Context (TocProvider in the layout). This prevents jank and ensures the TOC is always in sync with the page content.
The OnThisPage component uses bounding-rect proximity tracking (not Intersection Observer) to determine the active heading. This keeps the TOC active as the user reads, not just when a heading enters the viewport.
Placeholder pages (coming soon) use dynamic segments ([topic]) with generateStaticParams for static pre-rendering:
export async function generateStaticParams() {
const dir = path.join(process.cwd(), 'content/docs/concepts')
return fs.readdirSync(dir)
.filter(f => f.endsWith('.md'))
.map(f => ({ topic: f.replace(/\.md$/, '') }))
}This generates routes for all .md files at build time, avoiding 404s while keeping the file count low.
- Static builds: Run
bun run buildbefore deployment. Next.js pre-renders all docs pages. - Code splitting: Route pages are lazy-loaded; only the current page's code is downloaded.
- Smooth scrolling: Enabled globally in
app/globals.cssviahtml { scroll-behavior: smooth; }.
# Kill the process using port 3000, or specify a different port
bun run dev --port 3001Restart the dev server:
# Press Ctrl+C to stop
bun run devCheck the Markdown syntax:
- YAML frontmatter must be at the top, enclosed in
--- - Code blocks need a language specifier (e.g.,
```bash) - Callout tags must have
typeattribute:{% callout type="info" %}
- Create a branch for your docs changes
- Add or edit
.mdfiles incontent/docs/ - Update navigation in
lib/docs-navigation.tsif adding new pages - Test locally:
bun run dev - Build for production:
bun run build - Commit and push; open a PR
The site is built as a static Next.js app suitable for:
- Vercel (native Next.js support)
- Netlify (via
next export) - Self-hosted (using
bun startor a Node.js runtime)
For static export (when dynamic routes aren't needed):
# In next.config.ts, set output: 'export'
bun run build
# Outputs to ./out/Canonical docs (G6.4). This site (auths-docs, Next.js + Markdoc) is the single canonical, dev-facing documentation surface. The older docs/getting-started/ tree in the auths repo (its mkdocs site) is superseded and slated for retirement — until it is removed there, treat anything in it as stale and defer to this site. The quickstart is the canonical "getting started" entry; legacy getting-started URLs redirect to it via next.config.ts.
Cross-repo follow-up: retiring/redirecting
auths/docs/getting-started/is done in theauthsrepo (separate repo/session), not here.
Deferred: CI command-name lint. A CI check that fails the build when the docs reference a CLI command not in the real RootCommand (auths/crates/auths-cli/src/cli.rs) is planned but not yet implemented — this site has no CI yet. Candidate mechanisms when it's built:
- Local allowlist (lightweight): a GitHub Action greps fenced
```bashblocks forauths <cmd>and checks them against the known visible command set (init, sign, verify, status, whoami, demo, pair, trust, doctor, tutorial, config, completions). Fast (bun/Node, no Rust toolchain); the list must be kept in sync withcli.rs. - Build the binary (authoritative): check out the
authsrepo, buildauths, and reuse itsxtask gen-docs --checkto enumerate commands from the binary. Self-updating but heavy (Rust toolchain + cross-repo checkout) for a docs site.
Until it lands, use the manual guard: grep -rEoh 'auths [a-z-]+' content/docs | sort -u and eyeball against the set above.
- Auths GitHub
- Agent hello-world (
auths-agent-demo) — the canonical agent/SDK demo (delegated, scoped, revocable agent identities; Python SDK) - Next.js Documentation
- Markdoc Documentation
- Tailwind CSS