Skip to main content
OwnDocs

Introduction

12 min read

OwnDocs turns Markdown files into a documentation site with search, sidebar navigation, and password protection. It runs on Next.js 16, React 19, TypeScript 6, and Tailwind CSS 4.

Use it for an external API reference, an internal knowledge base, or customer-facing product guides. The page structure, components, and hosting setup come ready-made, so you're not building a docs site from scratch.

Why OwnDocs

Most documentation tools make you choose between control and setup time. Static site generators give you control but ask for hours of plugin configuration. Hosted platforms run the infrastructure for you but charge per seat and limit what you can change. OwnDocs ships as source code you own. It works without extra setup, and you can change any part of it.

Pages from files, no configuration. Create an .mdx file and write. OwnDocs builds the sidebar, search index, breadcrumbs, table of contents, sitemap, OpenGraph metadata, and static pages for you. There's no routing config or build plugin to set up.

29 ready-made documentation components. They cover the patterns that keep coming up in technical writing: API endpoint docs, structured parameter fields, tabbed code groups, feature comparisons, step-by-step guides, release notes, and diagrams.

Two access modes, one codebase. One ACCESS_MODE environment variable switches between private (password-protected) and public (open) access. One deployment can serve internal team docs, client portals, and public product docs.

You own the source. OwnDocs is a one-time purchase with an MIT license. No per-seat fees, no monthly subscriptions, no vendor lock-in. Deploy on Vercel, AWS, DigitalOcean, or your own server.

Technology Stack

OwnDocs is built on these libraries:

  • Next.js v16 — App Router with Turbopack for sub-second hot reload, server and static rendering, and proxy middleware for authentication
  • React v19 — Server Components and concurrent rendering for fast first paint and responsive pages
  • MDX v3 — Markdown with embedded React components via next-mdx-remote
  • Tailwind CSS v4 — Utility-first styling with OKLCH color space for consistent color themes across all 26 palettes
  • Prism.js v1.30 — Client-side syntax highlighting for 65+ programming languages with hydration-safe rendering
  • Mermaid v11 — Diagram rendering for 15+ diagram types with DOMPurify SVG sanitization for security
  • Jose v6 — JWT-based authentication with HS256 signing for sessions
  • DOMPurify v3 — SVG sanitization for all diagram output, which blocks XSS attacks
  • Lucide React v1.0 — Icon library used across 29 components
  • TypeScript v6 — Type safety across every source file in the project

Core Capabilities

Content Authoring

OwnDocs supports the content formats you'll need in a docs site:

  • File-based routing — Every .mdx file in app/ becomes a page. The file path is the URL. No routing configuration needed.
  • MDX support — Write Markdown with embedded React components. 29 custom components are available on every page without imports.
  • GitHub Flavored Markdown — Tables, strikethrough, task lists, and autolinks via remark-gfm
  • GitHub-style alerts — Six alert types (note, tip, important, warning, caution, danger) for flagging important information
  • Frontmatter support — YAML metadata parsed via gray-matter for page descriptions used in SEO and search results
  • Internal link normalization.mdx extensions are stripped from links, so [Features](./features.mdx) and [Features](./features) both work
  • Copy page as Markdown — A dropdown button next to every page title copies the whole page as Markdown or plain text, ready to paste into ChatGPT, Claude, or Cursor

Code and Diagrams

Technical docs lean on readable code examples and diagrams. OwnDocs covers both:

  • Syntax highlighting — 65+ programming languages with Prism.js client-side highlighting and dependency ordering handled for you
  • 45 language aliases — Common shortcuts like js, ts, py, sh, kt, rs, rb, tf, sol, and more
  • Line numbers — Line numbering with a configurable start offset
  • Line highlighting — Highlight specific lines with {1,3-5} syntax to point out key code
  • Diff markers — Inline // [!code ++] and // [!code --] annotations for showing code changes without switching to diff format
  • Word highlighting — Highlight specific patterns with /pattern/ syntax to call out variables or functions
  • File titles — Show file path headers with title="filename" metastring so readers know where code belongs
  • Collapsible code — Long blocks collapse with expandable and maxLines=N to keep pages scannable while keeping full examples
  • Code groups — Tabbed code blocks for showing the same concept in multiple languages or package managers (npm/yarn/pnpm)
  • Copy to clipboard — One-click code copying with visual feedback on every code block
  • Mermaid diagrams — 15+ diagram types including flowchart, sequence, class, state, gantt, pie, ER, gitGraph, journey, mindmap, timeline, quadrant, sankey, and more
  • Diagram detection — Mermaid diagrams render without the mermaid language tag when the content starts with a recognized diagram keyword

Readers find what they need from the sidebar, search, and breadcrumbs. OwnDocs builds each one from your file structure:

  • Auto-generated sidebar — Built from the file system, with 3-level depth and active page highlighting
  • Acronym-aware name formatting — 140+ technical acronyms keep their capitalization (API, REST, GraphQL, MongoDB, JWT, SSO, RBAC, and more)
  • Full-text search — Client-side search across all pages with scored ranking and context snippets showing where the match was found
  • Keyboard shortcutCmd+K or Ctrl+K opens the search modal from any page, following the ARIA combobox pattern for screen readers
  • Heading anchors — Auto-generated slug IDs with clickable links via rehype-slug and rehype-autolink-headings for deep-linking
  • Table of contents — Scroll-spy TOC on desktop that highlights the current section, with a collapsible panel on mobile
  • Breadcrumb navigation — Auto-formatted path breadcrumbs on every page for orientation within the site hierarchy
  • Previous/next navigation — Sequential page links at the bottom of every article for linear reading
  • Auto-generated index<DynamicIndexContent /> builds a site map with page counts for landing pages
  • Category index — Directories without an index.mdx generate a landing page that lists all child pages

Documentation Components

OwnDocs ships 29 custom components. Each one is responsive, keyboard-accessible, and styled to match your theme:

  • ApiBlock — REST API endpoint documentation with 5 HTTP method badges, color-coded headers, request/response bodies, multi-response tabs, auth indicators, deprecation notices, rate limiting, base URLs, and generated cURL examples
  • ParamField — Structured parameter documentation with type, location (path, query, body, header), required/optional markers, default values, and deprecation labels
  • ResponseField — Structured response field documentation for API endpoints
  • CodeGroup — Tabbed code blocks with keyboard navigation for multi-language examples
  • Tabs / TabItem — General-purpose tabbed content panels with ARIA tablist pattern and localStorage sync
  • Steps — Numbered step-by-step guides with visual connectors for tutorials
  • Card / CardGrid — Feature showcase cards with configurable grid columns and optional icons
  • Accordion — Collapsible sections with smooth animation and URL hash deep-linking
  • Badge — Inline status indicators in five variants (default, info, success, warning, danger)
  • ComparisonTable — Side-by-side feature comparison with 10 visual indicator types and column highlighting
  • FileTree — Visual directory structure from indented text
  • ChangelogEntry / ChangelogLabel — Technical changelog timeline with 7 label types for developer audiences
  • ReleaseNote / ReleaseHighlight — User-facing release announcements with 8 highlight types for public "What's New" pages
  • ImageZoom — Click-to-zoom lightbox with keyboard and ARIA support
  • Embed — Responsive iframe embeds with URL allowlist (YouTube, GitHub) and sandbox security

Theming

OwnDocs ships 26 color themes. Each theme is a coordinated palette that generates light mode, dark mode, and component-level CSS custom properties:

  • 26 built-in palettes — emerald (default), amber, blue, cyan, fuchsia, gray, green, indigo, lime, mauve, mist, neutral, olive, orange, pink, purple, red, rose, sky, slate, stone, taupe, teal, violet, yellow, zinc
  • Dark mode toggle — Light, dark, and system modes with prefers-color-scheme detection and localStorage persistence
  • CSS custom properties — All colors defined as semantic variables (--color-accent, --color-bg-primary, and more) that switch between light and dark
  • Semantic aliases — Tailwind theme aliases (surface-*, content-*, edge-*, brand-*) switch with dark mode without dark: variant classes
  • Custom typography — Maven Pro for body text, JetBrains Mono for code with ligatures and slashed zeros

Security

OwnDocs protects private docs in these ways:

  • Password protection — JWT sessions with 14-day expiry via jose library
  • Browser fingerprinting — Sessions are invalidated if the User-Agent or Accept-Language header changes, which stops session hijacking
  • Secure cookies__Host- prefix, httpOnly, secure, sameSite: lax
  • Cookie name obfuscation — Cookie name derived from SHA-256 of COOKIE_SALT, making it unpredictable
  • Rate limiting — 5 login attempts per IP with 15-minute lockout and timing-safe password comparison to stop brute-force attempts
  • Origin validation — CSRF protection on all state-changing auth endpoints
  • 9 security headers — HSTS (2-year with preload), CSP, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection (disabled, superseded by CSP), Referrer-Policy, Permissions-Policy, X-Robots-Tag
  • 4-layer crawler blockingrobots.txt, HTML meta robots, X-Robots-Tag header, and password-gated access (private mode)
  • Path traversal checks — Slug validation rejects .. and leading /
  • DOMPurify — SVG sanitization on all Mermaid diagram output to block XSS

SEO and AI Readiness

In public mode, OwnDocs prepares every page for search engines and AI agents:

  • Dynamic sitemapsitemap.xml generated from the navigation tree
  • OpenGraph and Twitter Cards — Per-page og:title, og:description, and twitter:card meta tags with descriptions pulled from MDX content
  • Canonical URLs<link rel="canonical"> on every page to avoid duplicate content
  • JSON-LD structured dataTechArticle and BreadcrumbList schema.org markup on every documentation page for rich search results
  • Dynamic robots.txt — 28+ named bots blocked in private mode, full crawling permitted in public mode
  • llms.txt — AI agent index at /llms.txt listing all pages with URLs
  • llms-full.txt — Full documentation content at /llms-full.txt for bulk AI context loading
  • Copy page as Markdown — Dropdown button next to every H1 title with Markdown and plain text copy options for AI tools

Accessibility

OwnDocs follows WCAG guidelines for keyboard and screen reader support:

  • Skip to content — Keyboard-accessible skip link visible on focus
  • Focus management — H1 focused on route change so screen readers announce it
  • Focus-visible indicators — Visible keyboard focus rings on all interactive elements (WCAG 2.4.7)
  • ARIA patterns — Combobox on search, tablist on tabs/code groups, dialog on modals, region on code blocks
  • Keyboard navigation — Arrow keys, Home/End, Enter/Space across search, tabs, code groups, and accordions
  • Focus trapping — Search modal and image zoom trap focus within the dialog
  • Body scroll lock — Background scroll disabled when modals are open
  • Reduced motion — Respects prefers-reduced-motion system preference
  • Print stylesheet — Code rendering adjusted for print, interactive elements hidden
  • Content-visibilitycontent-visibility: auto on prose content to cut rendering work

Public/Private Access Mode

OwnDocs has two access modes set by one environment variable, so the same codebase can serve internal and public docs:

  • Private mode (default) — Password-protected access, all search engine and AI crawlers blocked, login required for every page
  • Public mode — Open access for all visitors, search engines allowed to index content, login page redirects to home, logout button hidden

Set via the ACCESS_MODE environment variable. The default is private.

Project Structure

Architecture

The diagrams below show how content moves through the build pipeline, how the layout organizes navigation components, and how the security and SEO layers fit in:

Environment Variables

All environment variables are generated by the setup script. You only need to change them if you want to customize the defaults:

  • ACCESS_MODEprivate (default) or public
  • APP_PASSWORD — Access password (private mode only)
  • JWT_SECRET — JWT signing key (private mode only)
  • COOKIE_SALT — Cookie name salt (private mode only)
  • THEME_VARIANT — Color palette (26 options, defaults to emerald)
  • NEXT_PUBLIC_SITE_URL — Site URL for sitemap and OG tags (optional, detected on Vercel)

Run bash scripts/setup-env.sh to generate all secrets, or copy .env.example as a starting point.

Quick Setup

Bash
Bash
git clone https://github.com/devops-infinity/owndocs.git my-docs
cd my-docs
bash scripts/setup-env.sh
npm install
npm run dev

Adding Content

Create any .mdx file under app/ and it becomes a documentation page:

Plain Text
Plain Text
app/guides/deployment.mdx  →  /guides/deployment
app/api-docs/endpoints.mdx →  /api-docs/endpoints

Directories become sidebar categories. Use numeric prefixes like 01-basics/ to control page ordering. Every new file is added to the sidebar, search index, sitemap, and navigation with no configuration.

Linting and Formatting

OwnDocs ships a linting and formatting pipeline to keep content and code consistent:

Bash
Bash
npm run format        # Format all files
npm run format:check  # Check without modifying
npm run lint          # ESLint for TS/JS
npm run lint:mdx      # ESLint for MDX
npm run mdx:check     # Remark lint for MDX/Markdown

The pipeline runs ESLint with TypeScript rules, eslint-plugin-mdx for MDX files, and remark-lint with the recommended and consistent presets. It also checks heading style, validates links, and runs remark-preset-prettier so remark rules don't fight Prettier formatting.

Was this page helpful?