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
Cloudflare Pages Password Protection (Recommended)
-
Deploy to Cloudflare Pages:
- GitHub Actions automatically deploys (see workflow above)
- Or connect
FishingLog.Documentationrepo manually - Build command:
npm run build - Publish directory:
build
-
Enable Password Protection:
- Cloudflare Dashboard → Pages →
fishinglog-docs - Settings → Access → Password Protection
- Enable and set password
- Done!
- Cloudflare Dashboard → Pages →
Result: https://fishinglog-docs.pages.dev (password protected)
Cloudflare Access (More Secure - Optional)
-
Deploy to Cloudflare Pages (same as above)
-
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/*.jsfiles - No
mkdocs.ymlneeded
Step 2: Update Links
- Relative links work the same
- Cross-repo links:
[Link](../mobile/docs/...) - Or use Docusaurus
@sitealias
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
| Feature | Current (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
| Solution | Cost | Setup Time |
|---|---|---|
| Current (Public GitHub Pages) | Free | ✅ Done |
| Split (Public + Private Cloudflare) | Free | 2-3 hours |
| Unified Docusaurus (Cloudflare Pages) | Free | 4-6 hours |
| GitHub Enterprise | $21/user/month | ✅ Easy |
Recommendation
✅ Go with Unified Docusaurus
Why:
- Scalable - Easy to add mobile/web/admin docs
- Professional - Better UX than MkDocs
- Unified - One site, one password
- Future-proof - Standard pattern
- 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.