Docusaurus คืออะไร
Docusaurus เป็น open source static site generator จาก Meta (Facebook) ออกแบบมาสำหรับสร้าง documentation websites โดยเฉพาะ ใช้ React เป็น base รองรับ MDX (Markdown + JSX), versioning, i18n, search และ blog ในตัว
Features หลักของ Docusaurus ได้แก่ MDX Support เขียน documentation ด้วย Markdown พร้อมใช้ React components ได้, Versioning จัดการหลาย versions ของ docs อัตโนมัติ, i18n Localization รองรับหลายภาษา built-in, Search Integration เชื่อมกับ Algolia DocSearch, Blog ระบบ blog built-in สำหรับ announcements, Theming ปรับแต่ง theme ด้วย CSS และ React components
Edge Computing สำหรับ Docusaurus หมายถึงการ deploy static site ไปยัง edge network (CDN) ทั่วโลก ทำให้ documentation load เร็วจากทุกที่ ใช้ edge functions สำหรับ dynamic features เช่น search, analytics, personalization โดยไม่ต้องมี origin server
ติดตั้งและเริ่มต้นใช้งาน Docusaurus
ขั้นตอนติดตั้ง Docusaurus
# === ติดตั้ง Docusaurus ===
# 1. Create Docusaurus Project
npx create-docusaurus@latest my-docs classic
cd my-docs
# 2. Project Structure
# my-docs/
# ├── blog/
# │ ├── 2025-01-15-welcome.md
# │ └── authors.yml
# ├── docs/
# │ ├── intro.md
# │ ├── tutorial-basics/
# │ │ ├── create-a-document.md
# │ │ └── deploy-your-site.md
# │ └── tutorial-extras/
# │ └── manage-docs-versions.md
# ├── src/
# │ ├── components/
# │ ├── css/
# │ │ └── custom.css
# │ └── pages/
# │ └── index.js
# ├── static/
# │ └── img/
# ├── docusaurus.config.js
# ├── sidebars.js
# └── package.json
# 3. docusaurus.config.js
cat > docusaurus.config.js << 'EOF'
const config = {
title: 'My Documentation',
tagline: 'Technical Documentation with Edge Computing',
favicon: 'img/favicon.ico',
url: 'https://docs.example.com',
baseUrl: '/',
organizationName: 'my-org',
projectName: 'my-docs',
i18n: {
defaultLocale: 'th',
locales: ['th', 'en'],
},
presets: [
[
'classic',
{
docs: {
sidebarPath: './sidebars.js',
editUrl: 'https://github.com/my-org/my-docs/tree/main/',
versions: {
current: { label: 'v3.0', path: 'v3' },
},
},
blog: {
showReadingTime: true,
editUrl: 'https://github.com/my-org/my-docs/tree/main/',
},
theme: {
customCss: './src/css/custom.css',
},
},
],
],
themeConfig: {
navbar: {
title: 'My Docs',
logo: { alt: 'Logo', src: 'img/logo.svg' },
items: [
{ type: 'docSidebar', sidebarId: 'tutorialSidebar', position: 'left', label: 'Tutorial' },
{ to: '/blog', label: 'Blog', position: 'left' },
{ type: 'docsVersionDropdown', position: 'right' },
{ type: 'localeDropdown', position: 'right' },
{ href: 'https://github.com/my-org/my-docs', label: 'GitHub', position: 'right' },
],
},
footer: {
style: 'dark',
links: [
{ title: 'Docs', items: [{ label: 'Tutorial', to: '/docs/intro' }] },
{ title: 'Community', items: [{ label: 'Discord', href: 'https://discord.gg/example' }] },
],
},
algolia: {
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indexName: 'my-docs',
},
},
};
module.exports = config;
EOF
# 4. Start Development Server
npm start
# Open http://localhost:3000
# 5. Build for Production
npm run build
# Output in build/ directory
echo "Docusaurus installed and configured"
สร้าง Documentation Site
เขียน documentation ด้วย MDX
# === Documentation Content ===
# 1. Create Doc with MDX
cat > docs/getting-started.mdx << 'MDXEOF'
---
sidebar_position: 1
title: เริ่มต้นใช้งาน
description: วิธีติดตั้งและเริ่มต้นใช้งาน
tags: [getting-started, installation]
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
# เริ่มต้นใช้งาน
## ติดตั้ง
```bash
npm install @my-org/sdk
```
```bash
yarn add @my-org/sdk
```
```bash
pnpm add @my-org/sdk
```
## Quick Start
```javascript title="app.js"
import { MySDK } from '@my-org/sdk';
const client = new MySDK({
apiKey: process.env.API_KEY,
region: 'ap-southeast-1',
});
const result = await client.getData({ limit: 10 });
console.log(result);
```
:::tip
ใช้ environment variables สำหรับ API keys
:::
:::warning
อย่า hardcode API keys ใน source code
:::
MDXEOF
# 2. Sidebar Configuration
cat > sidebars.js << 'EOF'
const sidebars = {
tutorialSidebar: [
'intro',
'getting-started',
{
type: 'category',
label: 'Basics',
items: [
'tutorial-basics/create-a-document',
'tutorial-basics/deploy-your-site',
],
},
{
type: 'category',
label: 'API Reference',
items: [
'api/authentication',
'api/endpoints',
'api/error-codes',
],
},
{
type: 'category',
label: 'Advanced',
items: [
'advanced/edge-functions',
'advanced/caching',
'advanced/monitoring',
],
},
],
};
module.exports = sidebars;
EOF
# 3. Custom Component
cat > src/components/APIEndpoint.js << 'EOF'
import React from 'react';
export default function APIEndpoint({ method, path, description }) {
const colors = {
GET: '#61affe',
POST: '#49cc90',
PUT: '#fca130',
DELETE: '#f93e3e',
};
return (
{method}
{path}
{description}
);
}
EOF
echo "Documentation content created"
Edge Deployment สำหรับ Docusaurus
Deploy Docusaurus ไปยัง edge
# === Edge Deployment ===
# 1. Cloudflare Pages Deployment
# ===================================
cat > .github/workflows/deploy.yml << 'EOF'
name: Deploy to Cloudflare Pages
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install Dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: }
accountId: }
projectName: my-docs
directory: build
gitHubToken: }
EOF
# 2. Netlify Deployment
# ===================================
cat > netlify.toml << 'EOF'
[build]
command = "npm run build"
publish = "build"
[build.environment]
NODE_VERSION = "20"
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/*.html"
[headers.values]
Cache-Control = "public, max-age=0, must-revalidate"
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-Content-Type-Options = "nosniff"
Referrer-Policy = "strict-origin-when-cross-origin"
[[redirects]]
from = "/docs"
to = "/docs/intro"
status = 301
EOF
# 3. Vercel Deployment
# ===================================
cat > vercel.json << 'EOF'
{
"framework": "docusaurus-2",
"buildCommand": "npm run build",
"outputDirectory": "build",
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
}
]
}
EOF
# 4. Edge Functions for Dynamic Features
# ===================================
# Cloudflare Pages Function for search analytics
cat > functions/api/search.js << 'EOF'
export async function onRequestPost(context) {
const { request, env } = context;
const body = await request.json();
const query = body.query || '';
// Log search query for analytics
// await env.ANALYTICS.writeDataPoint({
// blobs: [query],
// indexes: [request.cf?.country || 'unknown'],
// });
// Forward to Algolia or self-hosted search
const searchResponse = await fetch('https://search-api.example.com/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, limit: 10 }),
});
return searchResponse;
}
EOF
# 5. Build and Deploy
npm run build
# Deploy to chosen platform
# npx wrangler pages deploy build/
# netlify deploy --prod
# vercel --prod
echo "Edge deployment configured"
Customization และ Plugins
ปรับแต่ง Docusaurus
// === Docusaurus Customization ===
// 1. Custom CSS Theme
// src/css/custom.css
/*
:root {
--ifm-color-primary: #2563eb;
--ifm-color-primary-dark: #1d4ed8;
--ifm-color-primary-darker: #1e40af;
--ifm-color-primary-darkest: #1e3a8a;
--ifm-color-primary-light: #3b82f6;
--ifm-color-primary-lighter: #60a5fa;
--ifm-color-primary-lightest: #93c5fd;
--ifm-code-font-size: 95%;
--ifm-font-family-base: 'Inter', system-ui, sans-serif;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
[data-theme='dark'] {
--ifm-color-primary: #60a5fa;
--ifm-color-primary-dark: #3b82f6;
--ifm-background-color: #0f172a;
}
.hero {
background: linear-gradient(135deg, #1e3a8a, #7c3aed);
color: white;
}
article .markdown h2 {
border-bottom: 2px solid var(--ifm-color-primary);
padding-bottom: 8px;
}
*/
// 2. Custom Plugin — Reading Time Analytics
// plugins/reading-time-plugin.js
/*
module.exports = function readingTimePlugin(context, options) {
return {
name: 'reading-time-plugin',
async contentLoaded({ content, actions }) {
// Track reading time for each doc
},
injectHtmlTags() {
return {
headTags: [
{
tagName: 'script',
innerHTML: `
// Track reading progress
let maxScroll = 0;
window.addEventListener('scroll', () => {
const scrollPct = window.scrollY /
(document.body.scrollHeight - window.innerHeight) * 100;
maxScroll = Math.max(maxScroll, scrollPct);
});
window.addEventListener('beforeunload', () => {
// Send reading analytics
navigator.sendBeacon('/api/analytics', JSON.stringify({
path: window.location.pathname,
readPct: Math.round(maxScroll),
timeOnPage: Math.round(performance.now() / 1000),
}));
});
`,
},
],
};
},
};
};
*/
// 3. Custom Remark Plugin — Auto API Links
/*
const autoApiLinks = () => {
return (tree) => {
visit(tree, 'text', (node) => {
// Convert API references to links
node.value = node.value.replace(
/`(GET|POST|PUT|DELETE)\s+(\/api\/\S+)`/g,
(match, method, path) => {
return `[ ](/docs/api)`;
}
);
});
};
};
*/
// 4. Versioning
// Create a new version
// npm run docusaurus docs:version 2.0
// Version structure:
// versioned_docs/
// ├── version-1.0/
// │ └── intro.md
// └── version-2.0/
// └── intro.md
// versioned_sidebars/
// ├── version-1.0-sidebars.json
// └── version-2.0-sidebars.json
// versions.json
// 5. i18n Setup
// npm run write-translations -- --locale en
// Translate files in i18n/en/
console.log("Docusaurus customization configured");
Performance Optimization
เพิ่ม performance สำหรับ documentation site
# === Performance Optimization ===
# 1. Build Optimization
# ===================================
# docusaurus.config.js additions:
# module.exports = {
# ...config,
#
# // Minimize bundle size
# webpack: {
# jsLoader: (isServer) => ({
# loader: require.resolve('swc-loader'),
# options: {
# jsc: {
# parser: { syntax: 'typescript', tsx: true },
# transform: { react: { runtime: 'automatic' } },
# },
# },
# }),
# },
#
# // Future flags for better performance
# future: {
# experimental_faster: {
# swcJsLoader: true,
# swcJsMinimizer: true,
# swcHtmlMinimizer: true,
# lightningCssMinimizer: true,
# rspackBundler: true,
# mdxCrossCompilerCache: true,
# },
# },
# };
# 2. Image Optimization
# ===================================
# Use @docusaurus/plugin-ideal-image
npm install @docusaurus/plugin-ideal-image
# docusaurus.config.js:
# plugins: [
# ['@docusaurus/plugin-ideal-image', {
# quality: 70,
# max: 1030,
# min: 640,
# steps: 2,
# disableInDev: false,
# }],
# ],
# 3. Caching Headers
# ===================================
# _headers file (for Netlify/Cloudflare Pages)
cat > static/_headers << 'EOF'
/assets/*
Cache-Control: public, max-age=31536000, immutable
/*.js
Cache-Control: public, max-age=31536000, immutable
/*.css
Cache-Control: public, max-age=31536000, immutable
/img/*
Cache-Control: public, max-age=604800
/*.html
Cache-Control: public, max-age=0, must-revalidate
X-Content-Type-Options: nosniff
EOF
# 4. Preload Critical Resources
# ===================================
# In docusaurus.config.js headTags:
# headTags: [
# { tagName: 'link', attributes: { rel: 'preconnect', href: 'https://fonts.googleapis.com' } },
# { tagName: 'link', attributes: { rel: 'dns-prefetch', href: 'https://algolia.net' } },
# ],
# 5. Lighthouse Performance Targets
# ===================================
# Performance: > 95
# Accessibility: > 95
# Best Practices: > 95
# SEO: > 95
#
# Key metrics:
# - FCP < 1.0s (static site from CDN)
# - LCP < 1.5s
# - CLS < 0.05
# - TTI < 2.0s
# - Total bundle < 200KB gzipped
# 6. Monitoring Build Size
# ===================================
cat > scripts/check-bundle.sh << 'SHEOF'
#!/bin/bash
npm run build
# Check build output size
BUILD_SIZE=$(du -sh build/ | cut -f1)
echo "Build size: $BUILD_SIZE"
# Check individual chunks
echo "Largest files:"
find build/ -name "*.js" -exec du -sh {} \; | sort -rh | head -10
# Check HTML files
HTML_COUNT=$(find build/ -name "*.html" | wc -l)
echo "HTML pages: $HTML_COUNT"
SHEOF
chmod +x scripts/check-bundle.sh
echo "Performance optimization configured"
FAQ คำถามที่พบบ่อย
Q: Docusaurus กับ GitBook ต่างกันอย่างไร?
A: Docusaurus เป็น open source, self-hosted, ใช้ React/MDX, customizable มาก, ฟรีทั้งหมด deploy ได้ทุก static hosting (Netlify, Vercel, Cloudflare Pages) GitBook เป็น SaaS platform มี WYSIWYG editor ใช้งานง่ายกว่า มี collaboration features built-in แต่ customization จำกัด free tier จำกัด features สำหรับ developer documentation แนะนำ Docusaurus สำหรับ non-technical team แนะนำ GitBook
Q: Edge deployment ช่วย documentation site อย่างไร?
A: Documentation เป็น static content ที่เหมาะกับ edge deployment มาก ข้อดี TTFB ต่ำมาก (10-50ms จาก edge vs 200-500ms จาก origin), scale อัตโนมัติรองรับ traffic spikes (เช่น product launch), global availability ไม่มี single point of failure, ฟรีหรือราคาถูกมาก (Cloudflare Pages, Netlify, Vercel มี generous free tiers), HTTPS อัตโนมัติ documentation ส่วนใหญ่ไม่ต้อง server-side logic จึง deploy ที่ edge ได้ 100%
Q: Docusaurus รองรับ search อย่างไร?
A: มีหลายวิธี Algolia DocSearch (แนะนำ) ฟรีสำหรับ open source projects, search quality ดีมาก, ใช้ crawler index content อัตโนมัติ Local Search Plugin (@cmfcmf/docusaurus-search-local) ไม่ต้องใช้ external service ทำงาน offline ได้ แต่ index size ใหญ่สำหรับ docs เยอะ Typesense DocSearch alternative ที่ self-host ได้ Flexsearch lightweight client-side search
Q: วิธี handle multiple versions ของ docs?
A: Docusaurus มี built-in versioning ใช้ npx docusaurus docs:version X.X สร้าง version snapshot ของ docs ปัจจุบัน docs ใน docs/ folder เป็น "next" version (development) versioned docs อยู่ใน versioned_docs/ แต่ละ version มี sidebar แยก users เลือก version จาก dropdown ที่ navbar ข้อควรระวัง ทุก version เพิ่ม build time และ bundle size ลบ versions เก่าที่ไม่ support แล้วออก
