Skip to main content

Unified Docusaurus Documentation Setup

Why This Makes Sense

Not overboard - This is actually a best practice for multi-repo projects:

  • Facebook/Meta uses unified docs
  • Google uses unified docs
  • Microsoft uses unified docs
  • Many open-source projects do this

Benefits:

  • Single password-protected site
  • Unified search across all projects
  • Consistent navigation
  • Easy to add new projects
  • Professional appearance

Architecture

FishingLog.Documentation (New Repo)
├── docusaurus.config.js
├── sidebars/
│ ├── backend.js
│ ├── mobile.js
│ └── web.js
├── backend/ (git submodule → FishingLog.Backend)
│ └── docs/
├── mobile/ (git submodule → FishingLog.Mobile)
│ └── docs/
└── web/ (git submodule → FishingLog.Web)
└── docs/

Implementation Steps

Step 1: Create Documentation Repository

# Create new repo on GitHub: FishingLog.Documentation
mkdir FishingLog.Documentation
cd FishingLog.Documentation
git init
git remote add origin https://github.com/JamesWJager/FishingLog.Documentation.git

Step 2: Initialize Docusaurus

npx create-docusaurus@latest . classic --typescript

Step 3: Add Repositories as Git Submodules

# Add backend docs
git submodule add https://github.com/JamesWJager/FishingLog.Backend.git backend

# Future: Add other repos when ready
# git submodule add https://github.com/JamesWJager/FishingLog.Mobile.git mobile
# git submodule add https://github.com/JamesWJager/FishingLog.Web.git web

Step 4: Configure Multi-Instance Docs

docusaurus.config.js:

const config = {
title: 'FishingLog Platform Documentation',
tagline: 'Complete documentation for all FishingLog applications',
url: 'https://docs.reelog.app',
baseUrl: '/',
organizationName: 'JamesWJager',
projectName: 'FishingLog.Documentation',

presets: [
[
'@docusaurus/preset-classic',
{
docs: {
// Backend docs (main instance)
path: 'backend/docs',
routeBasePath: 'backend',
sidebarPath: require.resolve('./sidebars/backend.js'),
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
},
],
],

// Additional doc instances for other projects
plugins: [
[
'@docusaurus/plugin-content-docs',
{
id: 'mobile',
path: 'mobile/docs',
routeBasePath: 'mobile',
sidebarPath: require.resolve('./sidebars/mobile.js'),
},
],
[
'@docusaurus/plugin-content-docs',
{
id: 'web',
path: 'web/docs',
routeBasePath: 'web',
sidebarPath: require.resolve('./sidebars/web.js'),
},
],
],

themeConfig: {
navbar: {
title: 'FishingLog Docs',
items: [
{
type: 'doc',
docId: 'index',
position: 'left',
label: 'Backend API',
},
{
type: 'docSidebar',
sidebarId: 'mobile',
position: 'left',
label: 'Mobile App',
},
{
type: 'docSidebar',
sidebarId: 'web',
position: 'left',
label: 'Web App',
},
],
},
},
};

module.exports = config;

Step 5: Create Sidebar Configurations

sidebars/backend.js:

module.exports = {
backend: [
'index',
{
type: 'category',
label: 'Getting Started',
items: ['getting-started/installation', 'getting-started/local-development'],
},
{
type: 'category',
label: 'API',
items: ['api/endpoints', 'api/authentication'],
},
// ... rest of backend docs
],
};

Step 6: GitHub Actions Workflow

.github/workflows/deploy-docs.yml:

name: Deploy Unified Documentation

on:
push:
branches: [main]
workflow_dispatch:
# Trigger on submodule updates
repository_dispatch:
types: [backend-updated, mobile-updated, web-updated]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout with submodules
uses: actions/checkout@v4
with:
submodules: recursive
token: $\{\{ secrets.GITHUB_TOKEN \}\}

- name: Update Submodules
run: |
git submodule update --init --recursive
git submodule update --remote

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install Dependencies
run: npm ci

- name: Build Documentation
run: npm run build

- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: $\{\{ secrets.CLOUDFLARE_API_TOKEN \}\}
accountId: $\{\{ secrets.CLOUDFLARE_ACCOUNT_ID \}\}
projectName: fishinglog-docs
directory: build
gitHubToken: $\{\{ secrets.GITHUB_TOKEN \}\}

Step 7: Auto-Update Submodules

Option A: Manual Update (Simple)

# When backend docs change, update submodule
cd FishingLog.Documentation
git submodule update --remote backend
git commit -am "Update backend docs"
git push

Option B: Automatic via Webhook (Advanced)

  • Add webhook to each repo
  • Webhook triggers workflow on docs changes
  • Workflow updates submodule automatically

Password Protection Setup

  1. Deploy to Cloudflare Pages:

    • GitHub Actions automatically deploys (see workflow above)
    • Or connect FishingLog.Documentation repo manually
    • Build command: npm run build
    • Publish directory: build
  2. Enable Password Protection:

    • Cloudflare Dashboard → Pages → fishinglog-docs
    • Settings → Access → Password Protection
    • Enable and set password
    • Done!

Result: https://fishinglog-docs.pages.dev (password protected)

Cloudflare Access (More Secure - Optional)

  1. Deploy to Cloudflare Pages (same as above)

  2. Enable Cloudflare Access:

    • Cloudflare Dashboard → Access → Applications
    • Add application
    • Configure access policy (email domain, etc.)

Result: https://docs.reelog.app (email-based access)

Migration from MkDocs

Step 1: Convert Markdown Structure

Docusaurus uses similar markdown, but:

  • Frontmatter format: ---\ntitle: Title\n---
  • Sidebar defined in sidebars/*.js files
  • No mkdocs.yml needed
  • Relative links work the same
  • Cross-repo links: [Link](../mobile/docs/...)
  • Or use Docusaurus @site alias

Step 3: Migrate Content

Most markdown files work as-is. Main changes:

  • Add frontmatter to each file
  • Update navigation structure
  • Test links

Benefits Over Current Approach

FeatureCurrent (MkDocs)Unified Docusaurus
Multi-repo❌ Manual✅ Git submodules
Unified search❌ Separate✅ Cross-repo search
Password protection⚠️ Complex✅ Cloudflare Pages one-click
Navigation⚠️ Separate✅ Unified nav
Theming✅ Material✅ Many themes
Future projects⚠️ Manual setup✅ Add submodule

Cost Comparison

SolutionCostSetup Time
Current (Public GitHub Pages)Free✅ Done
Split (Public + Private Cloudflare)Free2-3 hours
Unified Docusaurus (Cloudflare Pages)Free4-6 hours
GitHub Enterprise$21/user/month✅ Easy

Recommendation

Go with Unified Docusaurus

Why:

  1. Scalable - Easy to add mobile/web/admin docs
  2. Professional - Better UX than MkDocs
  3. Unified - One site, one password
  4. Future-proof - Standard pattern
  5. Free - Cloudflare Pages free tier

Timeline:

  • Setup: 4-6 hours
  • Migration: 2-3 hours
  • Total: ~1 day of work

Worth it? Yes! Especially if you plan to add more projects.

Quick Start Command

# One-liner setup (after creating repo)
npx create-docusaurus@latest FishingLog.Documentation classic --typescript && \
cd FishingLog.Documentation && \
git submodule add https://github.com/JamesWJager/FishingLog.Backend.git backend

Then configure docusaurus.config.js and deploy to Cloudflare Pages!


Is this overboard? No! This is actually the professional way to do multi-repo documentation. Many companies use this exact pattern.