gitbook

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GitBook Documentation Skill

GitBook文档技能

Master GitBook for publishing professional documentation and books with spaces, collections, content variants, Git synchronization, team collaboration, and API integration. Build beautiful, searchable documentation sites with powerful collaboration features.
掌握GitBook的使用,借助空间、合集、内容版本变体、Git同步、团队协作及API集成功能,发布专业文档与书籍。打造具备强大协作功能的美观、可搜索的文档站点。

When to Use This Skill

何时使用此技能

USE GitBook when:

适合使用GitBook的场景:

  • Team documentation - Collaborative docs with multiple editors
  • Product documentation - User guides, API docs, tutorials
  • Knowledge bases - Internal wikis and knowledge management
  • Multi-version docs - Maintain docs for different product versions
  • Git-based workflow - Sync docs with GitHub/GitLab
  • Custom branding - Need custom domains and styling
  • Access control - Restrict docs to authenticated users
  • Quick setup - Need docs fast without build systems
  • 团队文档 - 支持多位编辑协作的文档
  • 产品文档 - 用户指南、API文档、教程
  • 知识库 - 内部维基与知识管理系统
  • 多版本文档 - 维护不同产品版本的文档
  • 基于Git的工作流 - 与GitHub/GitLab同步文档
  • 自定义品牌 - 需要自定义域名与样式
  • 访问控制 - 限制文档仅对已认证用户开放
  • 快速搭建 - 无需构建系统,快速创建文档

DON'T USE GitBook when:

不适合使用GitBook的场景:

  • Complex code docs - Use Sphinx for Python API docs
  • Static site control - Use MkDocs or Docusaurus
  • Offline-first - GitBook is primarily cloud-hosted
  • Self-hosted required - GitBook is SaaS (legacy self-hosted deprecated)
  • Free unlimited - Free tier has limitations
  • 复杂代码文档 - Python API文档建议使用Sphinx
  • 静态站点完全控制 - 建议使用MkDocs或Docusaurus
  • 优先离线使用 - GitBook主要为云托管服务
  • 必须自托管 - GitBook为SaaS服务(旧版自托管已弃用)
  • 无限免费使用 - 免费版存在功能限制

Prerequisites

前置条件

GitBook Account Setup

GitBook账户设置

bash
undefined
bash
undefined

2. Create an organization (or use personal space)

2. 创建组织(或使用个人空间)

3. Generate API token at:

3. 在以下地址生成API令牌:

Set environment variable

设置环境变量

export GITBOOK_API_TOKEN="gb_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export GITBOOK_API_TOKEN="gb_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Verify authentication

验证身份

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user" | jq '.id, .displayName'
undefined
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user" | jq '.id, .displayName'
undefined

Git Sync Setup

Git同步设置

bash
undefined
bash
undefined

In your GitBook space settings:

在GitBook空间设置中:

1. Go to Integrations > Git Sync

1. 进入Integrations > Git Sync

2. Connect GitHub/GitLab account

2. 连接GitHub/GitLab账户

3. Select repository and branch

3. 选择仓库与分支

Repository structure

仓库结构

docs-repo/ ├── README.md # Main page (or SUMMARY.md) ├── SUMMARY.md # Table of contents ├── chapter-1/ │ ├── README.md # Chapter intro │ ├── page-1.md │ └── page-2.md ├── chapter-2/ │ └── ... └── .gitbook.yaml # GitBook config (optional)
undefined
docs-repo/ ├── README.md # 主页(或SUMMARY.md) ├── SUMMARY.md # 目录 ├── chapter-1/ │ ├── README.md # 章节介绍 │ ├── page-1.md │ └── page-2.md ├── chapter-2/ │ └── ... └── .gitbook.yaml # GitBook配置(可选)
undefined

Python Setup

Python环境设置

bash
undefined
bash
undefined

Install dependencies

安装依赖

pip install requests python-dateutil
pip install requests python-dateutil

Using uv

使用uv安装

uv pip install requests python-dateutil
uv pip install requests python-dateutil

Verify

验证

python -c "import requests; print('Ready for GitBook integration!')"
undefined
python -c "import requests; print('Ready for GitBook integration!')"
undefined

Core Capabilities

核心功能

1. API Authentication

1. API身份验证

REST API Basics:
bash
undefined
REST API基础:
bash
undefined

GitBook API base URL

GitBook API基础URL

Get current user

获取当前用户信息

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/user" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/user" | jq

List organizations

列出所有组织

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs" | jq

Get organization details

获取组织详情

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID" | jq

**Python API Client:**
```python
import requests
from datetime import datetime
import os

class GitBookClient:
    """GitBook API client."""

    BASE_URL = "https://api.gitbook.com/v1"

    def __init__(self, api_token=None):
        self.api_token = api_token or os.environ.get("GITBOOK_API_TOKEN")
        self.headers = {
            "Authorization": f"Bearer {self.api_token}",
            "Content-Type": "application/json"
        }

    def _request(self, method, endpoint, data=None, params=None):
        """Make API request."""
        url = f"{self.BASE_URL}{endpoint}"
        response = requests.request(
            method,
            url,
            headers=self.headers,
            json=data,
            params=params
        )
        response.raise_for_status()
        return response.json() if response.text else None

    def get_user(self):
        """Get current user."""
        return self._request("GET", "/user")

    def list_organizations(self):
        """List all organizations."""
        return self._request("GET", "/orgs")

    def get_organization(self, org_id):
        """Get organization details."""
        return self._request("GET", f"/orgs/{org_id}")
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID" | jq

**Python API客户端:**
```python
import requests
from datetime import datetime
import os

class GitBookClient:
    """GitBook API客户端。"""

    BASE_URL = "https://api.gitbook.com/v1"

    def __init__(self, api_token=None):
        self.api_token = api_token or os.environ.get("GITBOOK_API_TOKEN")
        self.headers = {
            "Authorization": f"Bearer {self.api_token}",
            "Content-Type": "application/json"
        }

    def _request(self, method, endpoint, data=None, params=None):
        """发起API请求。"""
        url = f"{self.BASE_URL}{endpoint}"
        response = requests.request(
            method,
            url,
            headers=self.headers,
            json=data,
            params=params
        )
        response.raise_for_status()
        return response.json() if response.text else None

    def get_user(self):
        """获取当前用户信息。"""
        return self._request("GET", "/user")

    def list_organizations(self):
        """列出所有组织。"""
        return self._request("GET", "/orgs")

    def get_organization(self, org_id):
        """获取组织详情。"""
        return self._request("GET", f"/orgs/{org_id}")

Example usage

使用示例

if name == "main": client = GitBookClient()
user = client.get_user()
print(f"User: {user['displayName']}")

orgs = client.list_organizations()
for org in orgs.get("items", []):
    print(f"Org: {org['title']}")
undefined
if name == "main": client = GitBookClient()
user = client.get_user()
print(f"User: {user['displayName']}")

orgs = client.list_organizations()
for org in orgs.get("items", []):
    print(f"Org: {org['title']}")
undefined

2. Spaces Management

2. 空间管理

REST API - Spaces:
bash
undefined
REST API - 空间操作:
bash
undefined

List spaces in organization

列出组织下的所有空间

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/spaces" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/spaces" | jq

Get space details

获取空间详情

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID" | jq

Create space

创建空间

curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/spaces"
-d '{ "title": "API Documentation", "visibility": "public" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/spaces"
-d '{ "title": "API Documentation", "visibility": "public" }' | jq

Update space

更新空间

curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID"
-d '{ "title": "Updated API Documentation", "visibility": "private" }' | jq
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID"
-d '{ "title": "Updated API Documentation", "visibility": "private" }' | jq

Delete space

删除空间

curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID"
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID"

Get space content (pages)

获取空间内容(页面)

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq

**Python - Spaces:**
```python
class GitBookClient:
    # ... previous methods ...

    def list_spaces(self, org_id):
        """List all spaces in organization."""
        return self._request("GET", f"/orgs/{org_id}/spaces")

    def get_space(self, space_id):
        """Get space details."""
        return self._request("GET", f"/spaces/{space_id}")

    def create_space(self, org_id, title, visibility="public"):
        """Create a new space."""
        return self._request(
            "POST",
            f"/orgs/{org_id}/spaces",
            data={"title": title, "visibility": visibility}
        )

    def update_space(self, space_id, **kwargs):
        """Update space settings."""
        return self._request(
            "PATCH",
            f"/spaces/{space_id}",
            data=kwargs
        )

    def delete_space(self, space_id):
        """Delete a space."""
        return self._request("DELETE", f"/spaces/{space_id}")

    def get_space_content(self, space_id):
        """Get space content structure."""
        return self._request("GET", f"/spaces/{space_id}/content")
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq

**Python - 空间操作:**
```python
class GitBookClient:
    # ... 之前的方法 ...

    def list_spaces(self, org_id):
        """列出组织下的所有空间。"""
        return self._request("GET", f"/orgs/{org_id}/spaces")

    def get_space(self, space_id):
        """获取空间详情。"""
        return self._request("GET", f"/spaces/{space_id}")

    def create_space(self, org_id, title, visibility="public"):
        """创建新空间。"""
        return self._request(
            "POST",
            f"/orgs/{org_id}/spaces",
            data={"title": title, "visibility": visibility}
        )

    def update_space(self, space_id, **kwargs):
        """更新空间设置。"""
        return self._request(
            "PATCH",
            f"/spaces/{space_id}",
            data=kwargs
        )

    def delete_space(self, space_id):
        """删除空间。"""
        return self._request("DELETE", f"/spaces/{space_id}")

    def get_space_content(self, space_id):
        """获取空间内容结构。"""
        return self._request("GET", f"/spaces/{space_id}/content")

Example usage

使用示例

spaces = client.list_spaces("org_xxxxx") for space in spaces.get("items", []): print(f"Space: {space['title']} ({space['visibility']})")
spaces = client.list_spaces("org_xxxxx") for space in spaces.get("items", []): print(f"Space: {space['title']} ({space['visibility']})")

Create new space

创建新空间

new_space = client.create_space( org_id="org_xxxxx", title="Developer Guide", visibility="public" ) print(f"Created: {new_space['id']}")
undefined
new_space = client.create_space( org_id="org_xxxxx", title="Developer Guide", visibility="public" ) print(f"Created: {new_space['id']}")
undefined

3. Content Management

3. 内容管理

REST API - Content:
bash
undefined
REST API - 内容操作:
bash
undefined

Get page content

获取页面内容

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/page/PAGE_ID" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/page/PAGE_ID" | jq

List pages in space

列出空间内的所有页面

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq '.pages'
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content" | jq '.pages'

Import content from Git

从Git导入内容

curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/content/import/git"
-d '{ "url": "https://github.com/user/docs-repo", "ref": "main" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/content/import/git"
-d '{ "url": "https://github.com/user/docs-repo", "ref": "main" }' | jq

Export content

导出内容

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/export"
-o content-export.zip
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/content/export"
-o content-export.zip

Search content

搜索内容

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/search?query=installation" | jq

**Python - Content:**
```python
class GitBookClient:
    # ... previous methods ...

    def get_page(self, space_id, page_id):
        """Get page content."""
        return self._request(
            "GET",
            f"/spaces/{space_id}/content/page/{page_id}"
        )

    def list_pages(self, space_id):
        """List all pages in space."""
        content = self.get_space_content(space_id)
        return content.get("pages", [])

    def search_content(self, space_id, query):
        """Search content in space."""
        return self._request(
            "GET",
            f"/spaces/{space_id}/search",
            params={"query": query}
        )

    def import_from_git(self, space_id, repo_url, ref="main"):
        """Import content from Git repository."""
        return self._request(
            "POST",
            f"/spaces/{space_id}/content/import/git",
            data={"url": repo_url, "ref": ref}
        )
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/search?query=installation" | jq

**Python - 内容操作:**
```python
class GitBookClient:
    # ... 之前的方法 ...

    def get_page(self, space_id, page_id):
        """获取页面内容。"""
        return self._request(
            "GET",
            f"/spaces/{space_id}/content/page/{page_id}"
        )

    def list_pages(self, space_id):
        """列出空间内的所有页面。"""
        content = self.get_space_content(space_id)
        return content.get("pages", [])

    def search_content(self, space_id, query):
        """在空间内搜索内容。"""
        return self._request(
            "GET",
            f"/spaces/{space_id}/search",
            params={"query": query}
        )

    def import_from_git(self, space_id, repo_url, ref="main"):
        """从Git仓库导入内容。"""
        return self._request(
            "POST",
            f"/spaces/{space_id}/content/import/git",
            data={"url": repo_url, "ref": ref}
        )

Search example

搜索示例

results = client.search_content("space_xxxxx", "getting started") for result in results.get("items", []): print(f"Found: {result['title']} - {result['path']}")
undefined
results = client.search_content("space_xxxxx", "getting started") for result in results.get("items", []): print(f"Found: {result['title']} - {result['path']}")
undefined

4. Collections Management

4. 合集管理

REST API - Collections:
bash
undefined
REST API - 合集操作:
bash
undefined

List collections

列出所有合集

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/collections" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/collections" | jq

Get collection

获取合集详情

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID" | jq

Create collection

创建合集

curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/collections"
-d '{ "title": "Product Documentation", "description": "All product-related documentation" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/collections"
-d '{ "title": "Product Documentation", "description": "All product-related documentation" }' | jq

Add space to collection

向合集中添加空间

curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID" | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID" | jq

Remove space from collection

从合集中移除空间

curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID"
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces/SPACE_ID"

List spaces in collection

列出合集中的空间

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces" | jq

**Python - Collections:**
```python
class GitBookClient:
    # ... previous methods ...

    def list_collections(self, org_id):
        """List all collections in organization."""
        return self._request("GET", f"/orgs/{org_id}/collections")

    def get_collection(self, collection_id):
        """Get collection details."""
        return self._request("GET", f"/collections/{collection_id}")

    def create_collection(self, org_id, title, description=None):
        """Create a new collection."""
        data = {"title": title}
        if description:
            data["description"] = description

        return self._request(
            "POST",
            f"/orgs/{org_id}/collections",
            data=data
        )

    def add_space_to_collection(self, collection_id, space_id):
        """Add space to collection."""
        return self._request(
            "POST",
            f"/collections/{collection_id}/spaces/{space_id}"
        )

    def list_collection_spaces(self, collection_id):
        """List spaces in collection."""
        return self._request(
            "GET",
            f"/collections/{collection_id}/spaces"
        )
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/collections/COLLECTION_ID/spaces" | jq

**Python - 合集操作:**
```python
class GitBookClient:
    # ... 之前的方法 ...

    def list_collections(self, org_id):
        """列出组织下的所有合集。"""
        return self._request("GET", f"/orgs/{org_id}/collections")

    def get_collection(self, collection_id):
        """获取合集详情。"""
        return self._request("GET", f"/collections/{collection_id}")

    def create_collection(self, org_id, title, description=None):
        """创建新合集。"""
        data = {"title": title}
        if description:
            data["description"] = description

        return self._request(
            "POST",
            f"/orgs/{org_id}/collections",
            data=data
        )

    def add_space_to_collection(self, collection_id, space_id):
        """向合集中添加空间。"""
        return self._request(
            "POST",
            f"/collections/{collection_id}/spaces/{space_id}"
        )

    def list_collection_spaces(self, collection_id):
        """列出合集中的空间。"""
        return self._request(
            "GET",
            f"/collections/{collection_id}/spaces"
        )

Create collection and add spaces

创建合集并添加空间

collection = client.create_collection( org_id="org_xxxxx", title="API Reference", description="All API documentation" )
client.add_space_to_collection(collection["id"], "space_xxxxx")
undefined
collection = client.create_collection( org_id="org_xxxxx", title="API Reference", description="All API documentation" )
client.add_space_to_collection(collection["id"], "space_xxxxx")
undefined

5. Content Variants (Versions)

5. 内容版本变体(多版本)

REST API - Variants:
bash
undefined
REST API - 版本变体操作:
bash
undefined

List variants for space

列出空间的所有版本变体

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants" | jq

Create variant

创建版本变体

curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/variants"
-d '{ "title": "v2.0", "slug": "v2" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/variants"
-d '{ "title": "v2.0", "slug": "v2" }' | jq

Get variant content

获取版本变体内容

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/content" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/content" | jq

Set primary variant

设置主版本变体

curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/primary" | jq
curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID/primary" | jq

Delete variant

删除版本变体

curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID"

**Python - Variants:**
```python
class GitBookClient:
    # ... previous methods ...

    def list_variants(self, space_id):
        """List all variants for space."""
        return self._request("GET", f"/spaces/{space_id}/variants")

    def create_variant(self, space_id, title, slug):
        """Create a new variant."""
        return self._request(
            "POST",
            f"/spaces/{space_id}/variants",
            data={"title": title, "slug": slug}
        )

    def get_variant_content(self, space_id, variant_id):
        """Get variant content."""
        return self._request(
            "GET",
            f"/spaces/{space_id}/variants/{variant_id}/content"
        )

    def set_primary_variant(self, space_id, variant_id):
        """Set variant as primary."""
        return self._request(
            "PUT",
            f"/spaces/{space_id}/variants/{variant_id}/primary"
        )
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/variants/VARIANT_ID"

**Python - 版本变体操作:**
```python
class GitBookClient:
    # ... 之前的方法 ...

    def list_variants(self, space_id):
        """列出空间的所有版本变体。"""
        return self._request("GET", f"/spaces/{space_id}/variants")

    def create_variant(self, space_id, title, slug):
        """创建新的版本变体。"""
        return self._request(
            "POST",
            f"/spaces/{space_id}/variants",
            data={"title": title, "slug": slug}
        )

    def get_variant_content(self, space_id, variant_id):
        """获取版本变体内容。"""
        return self._request(
            "GET",
            f"/spaces/{space_id}/variants/{variant_id}/content"
        )

    def set_primary_variant(self, space_id, variant_id):
        """设置主版本变体。"""
        return self._request(
            "PUT",
            f"/spaces/{space_id}/variants/{variant_id}/primary"
        )

Create version variants

创建版本变体

client.create_variant("space_xxxxx", "Version 1.0", "v1") client.create_variant("space_xxxxx", "Version 2.0", "v2") client.set_primary_variant("space_xxxxx", "variant_v2")
undefined
client.create_variant("space_xxxxx", "Version 1.0", "v1") client.create_variant("space_xxxxx", "Version 2.0", "v2") client.set_primary_variant("space_xxxxx", "variant_v2")
undefined

6. Git Synchronization

6. Git同步

GitBook YAML Configuration:
yaml
undefined
GitBook YAML配置:
yaml
undefined

.gitbook.yaml - Repository configuration

.gitbook.yaml - 仓库配置

Root path for documentation

文档根路径

root: ./docs/
root: ./docs/

Structure file (table of contents)

结构文件(目录)

structure: readme: README.md summary: SUMMARY.md
structure: readme: README.md summary: SUMMARY.md

Redirects for moved pages

页面移动后的重定向

redirects: old-page: new-page.md moved/page: new-location/page.md

**SUMMARY.md Structure:**
```markdown
redirects: old-page: new-page.md moved/page: new-location/page.md

**SUMMARY.md结构:**
```markdown

Summary

Summary

Getting Started

Getting Started

  • Introduction
  • Installation
  • Quick Start
  • Configuration
  • Introduction
  • Installation
  • Quick Start
  • Configuration

User Guide

User Guide

  • Overview
  • Basic Usage
  • Advanced Topics
    • Topic 1
    • Topic 2
  • Overview
  • Basic Usage
  • Advanced Topics
    • Topic 1
    • Topic 2

API Reference

API Reference

  • REST API
  • SDKs
  • Webhooks
  • REST API
  • SDKs
  • Webhooks

Resources

Resources

  • FAQ
  • Troubleshooting
  • Changelog

**Git Workflow Script:**
```python
#!/usr/bin/env python3
"""gitbook_sync.py - GitBook Git synchronization helper"""

import subprocess
import os
from pathlib import Path

class GitBookSyncHelper:
    """Helper for GitBook Git synchronization."""

    def __init__(self, repo_path, docs_path="docs"):
        self.repo_path = Path(repo_path)
        self.docs_path = self.repo_path / docs_path

    def validate_structure(self):
        """Validate GitBook structure."""
        issues = []

        # Check for SUMMARY.md
        summary_path = self.docs_path / "SUMMARY.md"
        if not summary_path.exists():
            issues.append("Missing SUMMARY.md")

        # Check for README.md
        readme_path = self.docs_path / "README.md"
        if not readme_path.exists():
            issues.append("Missing README.md")

        # Validate SUMMARY.md links
        if summary_path.exists():
            with open(summary_path) as f:
                content = f.read()

            import re
            links = re.findall(r'\[.*?\]\((.*?\.md)\)', content)

            for link in links:
                file_path = self.docs_path / link
                if not file_path.exists():
                    issues.append(f"Broken link: {link}")

        return issues

    def generate_summary(self, exclude_patterns=None):
        """Auto-generate SUMMARY.md from directory structure."""
        exclude_patterns = exclude_patterns or ["_*", ".*"]

        lines = ["# Summary\n"]

        def process_dir(dir_path, indent=0):
            items = sorted(dir_path.iterdir())

            for item in items:
                # Skip excluded patterns
                if any(item.match(p) for p in exclude_patterns):
                    continue

                relative_path = item.relative_to(self.docs_path)

                if item.is_dir():
                    # Check for README.md in directory
                    readme = item / "README.md"
                    if readme.exists():
                        title = self._get_title(readme) or item.name
                        lines.append(
                            f"{'  ' * indent}* [{title}]({relative_path}/README.md)"
                        )
                    else:
                        lines.append(f"\n{'  ' * indent}## {item.name}\n")

                    process_dir(item, indent + 1)

                elif item.suffix == ".md" and item.name != "README.md":
                    title = self._get_title(item) or item.stem
                    lines.append(
                        f"{'  ' * indent}* [{title}]({relative_path})"
                    )

        process_dir(self.docs_path)
        return "\n".join(lines)

    def _get_title(self, md_path):
        """Extract title from markdown file."""
        with open(md_path) as f:
            for line in f:
                if line.startswith("# "):
                    return line[2:].strip()
        return None

    def sync_to_git(self, message="Update documentation"):
        """Commit and push changes."""
        os.chdir(self.repo_path)

        subprocess.run(["git", "add", "-A"])
        subprocess.run(["git", "commit", "-m", message])
        subprocess.run(["git", "push"])
  • FAQ
  • Troubleshooting
  • Changelog

**Git工作流脚本:**
```python
#!/usr/bin/env python3
"""gitbook_sync.py - GitBook Git同步助手"""

import subprocess
import os
from pathlib import Path

class GitBookSyncHelper:
    """GitBook Git同步助手。"""

    def __init__(self, repo_path, docs_path="docs"):
        self.repo_path = Path(repo_path)
        self.docs_path = self.repo_path / docs_path

    def validate_structure(self):
        """验证GitBook结构。"""
        issues = []

        # 检查SUMMARY.md是否存在
        summary_path = self.docs_path / "SUMMARY.md"
        if not summary_path.exists():
            issues.append("Missing SUMMARY.md")

        # 检查README.md是否存在
        readme_path = self.docs_path / "README.md"
        if not readme_path.exists():
            issues.append("Missing README.md")

        # 验证SUMMARY.md中的链接
        if summary_path.exists():
            with open(summary_path) as f:
                content = f.read()

            import re
            links = re.findall(r'\[.*?\]\((.*?\.md)\)', content)

            for link in links:
                file_path = self.docs_path / link
                if not file_path.exists():
                    issues.append(f"Broken link: {link}")

        return issues

    def generate_summary(self, exclude_patterns=None):
        """根据目录结构自动生成SUMMARY.md。"""
        exclude_patterns = exclude_patterns or ["_*", ".*"]

        lines = ["# Summary\n"]

        def process_dir(dir_path, indent=0):
            items = sorted(dir_path.iterdir())

            for item in items:
                # 跳过排除的文件/目录
                if any(item.match(p) for p in exclude_patterns):
                    continue

                relative_path = item.relative_to(self.docs_path)

                if item.is_dir():
                    # 检查目录中是否有README.md
                    readme = item / "README.md"
                    if readme.exists():
                        title = self._get_title(readme) or item.name
                        lines.append(
                            f"{'  ' * indent}* [{title}]({relative_path}/README.md)"
                        )
                    else:
                        lines.append(f"\n{'  ' * indent}## {item.name}\n")

                    process_dir(item, indent + 1)

                elif item.suffix == ".md" and item.name != "README.md":
                    title = self._get_title(item) or item.stem
                    lines.append(
                        f"{'  ' * indent}* [{title}]({relative_path})"
                    )

        process_dir(self.docs_path)
        return "\n".join(lines)

    def _get_title(self, md_path):
        """从Markdown文件中提取标题。"""
        with open(md_path) as f:
            for line in f:
                if line.startswith("# "):
                    return line[2:].strip()
        return None

    def sync_to_git(self, message="Update documentation"):
        """提交并推送更改。"""
        os.chdir(self.repo_path)

        subprocess.run(["git", "add", "-A"])
        subprocess.run(["git", "commit", "-m", message])
        subprocess.run(["git", "push"])

Example usage

使用示例

if name == "main": helper = GitBookSyncHelper("./my-docs-repo", "docs")
# Validate
issues = helper.validate_structure()
if issues:
    print("Structure issues found:")
    for issue in issues:
        print(f"  - {issue}")
else:
    print("Structure valid!")

# Generate SUMMARY.md
summary = helper.generate_summary()
print("\nGenerated SUMMARY.md:")
print(summary)
undefined
if name == "main": helper = GitBookSyncHelper("./my-docs-repo", "docs")
# 验证结构
issues = helper.validate_structure()
if issues:
    print("Structure issues found:")
    for issue in issues:
        print(f"  - {issue}")
else:
    print("Structure valid!")

# 生成SUMMARY.md
summary = helper.generate_summary()
print("\nGenerated SUMMARY.md:")
print(summary)
undefined

7. Team Collaboration

7. 团队协作

REST API - Members:
bash
undefined
REST API - 成员管理:
bash
undefined

List organization members

列出组织成员

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members" | jq

Invite member

邀请成员

curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/invites"
-d '{ "email": "user@example.com", "role": "editor" }' | jq
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/invites"
-d '{ "email": "user@example.com", "role": "editor" }' | jq

Update member role

更新成员角色

curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
-d '{ "role": "admin" }' | jq
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
-d '{ "role": "admin" }' | jq

Remove member

移除成员

curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"
curl -s -X DELETE -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/members/MEMBER_ID"

List pending invites

列出待处理的邀请

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/invites" | jq

**Python - Collaboration:**
```python
class GitBookClient:
    # ... previous methods ...

    def list_members(self, org_id):
        """List organization members."""
        return self._request("GET", f"/orgs/{org_id}/members")

    def invite_member(self, org_id, email, role="editor"):
        """Invite member to organization."""
        return self._request(
            "POST",
            f"/orgs/{org_id}/invites",
            data={"email": email, "role": role}
        )

    def update_member_role(self, org_id, member_id, role):
        """Update member's role."""
        return self._request(
            "PATCH",
            f"/orgs/{org_id}/members/{member_id}",
            data={"role": role}
        )

    def remove_member(self, org_id, member_id):
        """Remove member from organization."""
        return self._request(
            "DELETE",
            f"/orgs/{org_id}/members/{member_id}"
        )
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/orgs/ORG_ID/invites" | jq

**Python - 协作管理:**
```python
class GitBookClient:
    # ... 之前的方法 ...

    def list_members(self, org_id):
        """列出组织成员。"""
        return self._request("GET", f"/orgs/{org_id}/members")

    def invite_member(self, org_id, email, role="editor"):
        """邀请成员加入组织。"""
        return self._request(
            "POST",
            f"/orgs/{org_id}/invites",
            data={"email": email, "role": role}
        )

    def update_member_role(self, org_id, member_id, role):
        """更新成员角色。"""
        return self._request(
            "PATCH",
            f"/orgs/{org_id}/members/{member_id}",
            data={"role": role}
        )

    def remove_member(self, org_id, member_id):
        """从组织中移除成员。"""
        return self._request(
            "DELETE",
            f"/orgs/{org_id}/members/{member_id}"
        )

Roles: "admin", "creator", "editor", "reviewer", "reader"

角色选项: "admin", "creator", "editor", "reviewer", "reader"

client.invite_member("org_xxxxx", "newuser@example.com", role="editor")
undefined
client.invite_member("org_xxxxx", "newuser@example.com", role="editor")
undefined

8. Custom Domains and Branding

8. 自定义域名与品牌

REST API - Customization:
bash
undefined
REST API - 自定义设置:
bash
undefined

Get space customization

获取空间自定义设置

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization" | jq

Update customization

更新自定义设置

curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization"
-d '{ "favicon": "https://example.com/favicon.ico", "logo": { "light": "https://example.com/logo-light.png", "dark": "https://example.com/logo-dark.png" }, "themes": { "default": "light", "toggeable": true }, "styling": { "primaryColor": "#0066FF", "font": "Inter" } }' | jq
curl -s -X PATCH -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization"
-d '{ "favicon": "https://example.com/favicon.ico", "logo": { "light": "https://example.com/logo-light.png", "dark": "https://example.com/logo-dark.png" }, "themes": { "default": "light", "toggeable": true }, "styling": { "primaryColor": "#0066FF", "font": "Inter" } }' | jq

Get custom domain settings

获取自定义域名设置

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname" | jq
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname" | jq

Set custom domain

设置自定义域名

curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname"
-d '{ "hostname": "docs.example.com" }' | jq

**Python - Customization:**
```python
class GitBookClient:
    # ... previous methods ...

    def get_customization(self, space_id):
        """Get space customization settings."""
        return self._request(
            "GET",
            f"/spaces/{space_id}/publishing/customization"
        )

    def update_customization(self, space_id, settings):
        """Update space customization."""
        return self._request(
            "PATCH",
            f"/spaces/{space_id}/publishing/customization",
            data=settings
        )

    def set_custom_domain(self, space_id, hostname):
        """Set custom domain for space."""
        return self._request(
            "PUT",
            f"/spaces/{space_id}/publishing/customization/hostname",
            data={"hostname": hostname}
        )
curl -s -X PUT -H "Authorization: Bearer $GITBOOK_API_TOKEN"
-H "Content-Type: application/json"
"$API_BASE/spaces/SPACE_ID/publishing/customization/hostname"
-d '{ "hostname": "docs.example.com" }' | jq

**Python - 自定义设置:**
```python
class GitBookClient:
    # ... 之前的方法 ...

    def get_customization(self, space_id):
        """获取空间自定义设置。"""
        return self._request(
            "GET",
            f"/spaces/{space_id}/publishing/customization"
        )

    def update_customization(self, space_id, settings):
        """更新空间自定义设置。"""
        return self._request(
            "PATCH",
            f"/spaces/{space_id}/publishing/customization",
            data=settings
        )

    def set_custom_domain(self, space_id, hostname):
        """为空间设置自定义域名。"""
        return self._request(
            "PUT",
            f"/spaces/{space_id}/publishing/customization/hostname",
            data={"hostname": hostname}
        )

Update branding

更新品牌设置

client.update_customization("space_xxxxx", { "styling": { "primaryColor": "#6366F1", "font": "Inter" }, "themes": { "default": "light", "toggeable": True } })
undefined
client.update_customization("space_xxxxx", { "styling": { "primaryColor": "#6366F1", "font": "Inter" }, "themes": { "default": "light", "toggeable": True } })
undefined

Complete Examples

完整示例

Example 1: Documentation Site Builder

示例1:文档站点构建器

python
#!/usr/bin/env python3
"""docs_site_builder.py - Build complete documentation site"""

import os
from datetime import datetime
import json

class DocsSiteBuilder:
    """Build and manage GitBook documentation sites."""

    def __init__(self, api_token, org_id):
        self.client = GitBookClient(api_token)
        self.org_id = org_id

    def create_docs_site(
        self,
        title,
        description=None,
        visibility="public",
        custom_domain=None,
        branding=None
    ):
        """
        Create complete documentation site.

        Args:
            title: Site title
            description: Site description
            visibility: "public" or "private"
            custom_domain: Custom domain name
            branding: Branding settings dict

        Returns:
            Space details
        """
        # Create space
        space = self.client.create_space(
            org_id=self.org_id,
            title=title,
            visibility=visibility
        )

        space_id = space["id"]
        print(f"Created space: {space_id}")

        # Apply customization
        if branding:
            self.client.update_customization(space_id, branding)
            print("Applied branding")

        # Set custom domain
        if custom_domain:
            self.client.set_custom_domain(space_id, custom_domain)
            print(f"Set custom domain: {custom_domain}")

        return space

    def setup_versioned_docs(self, space_id, versions):
        """
        Set up version variants for documentation.

        Args:
            space_id: Space ID
            versions: List of version dicts with title and slug
        """
        for version in versions:
            variant = self.client.create_variant(
                space_id,
                title=version["title"],
                slug=version["slug"]
            )
            print(f"Created variant: {version['title']}")

            if version.get("primary"):
                self.client.set_primary_variant(space_id, variant["id"])
                print(f"Set {version['title']} as primary")

    def create_docs_collection(self, title, space_ids):
        """
        Create collection and add spaces.

        Args:
            title: Collection title
            space_ids: List of space IDs to add
        """
        collection = self.client.create_collection(
            org_id=self.org_id,
            title=title
        )

        for space_id in space_ids:
            self.client.add_space_to_collection(collection["id"], space_id)

        print(f"Created collection '{title}' with {len(space_ids)} spaces")
        return collection
python
#!/usr/bin/env python3
"""docs_site_builder.py - 构建完整的文档站点"""

import os
from datetime import datetime
import json

class DocsSiteBuilder:
    """构建并管理GitBook文档站点。"""

    def __init__(self, api_token, org_id):
        self.client = GitBookClient(api_token)
        self.org_id = org_id

    def create_docs_site(
        self,
        title,
        description=None,
        visibility="public",
        custom_domain=None,
        branding=None
    ):
        """
        创建完整的文档站点。

        参数:
            title: 站点标题
            description: 站点描述
            visibility: "public" 或 "private"
            custom_domain: 自定义域名
            branding: 品牌设置字典

        返回:
            空间详情
        """
        # 创建空间
        space = self.client.create_space(
            org_id=self.org_id,
            title=title,
            visibility=visibility
        )

        space_id = space["id"]
        print(f"Created space: {space_id}")

        # 应用自定义品牌设置
        if branding:
            self.client.update_customization(space_id, branding)
            print("Applied branding")

        # 设置自定义域名
        if custom_domain:
            self.client.set_custom_domain(space_id, custom_domain)
            print(f"Set custom domain: {custom_domain}")

        return space

    def setup_versioned_docs(self, space_id, versions):
        """
        为文档设置多版本变体。

        参数:
            space_id: 空间ID
            versions: 包含title和slug的版本字典列表
        """
        for version in versions:
            variant = self.client.create_variant(
                space_id,
                title=version["title"],
                slug=version["slug"]
            )
            print(f"Created variant: {version['title']}")

            if version.get("primary"):
                self.client.set_primary_variant(space_id, variant["id"])
                print(f"Set {version['title']} as primary")

    def create_docs_collection(self, title, space_ids):
        """
        创建合集并添加空间。

        参数:
            title: 合集标题
            space_ids: 要添加的空间ID列表
        """
        collection = self.client.create_collection(
            org_id=self.org_id,
            title=title
        )

        for space_id in space_ids:
            self.client.add_space_to_collection(collection["id"], space_id)

        print(f"Created collection '{title}' with {len(space_ids)} spaces")
        return collection

Example usage

使用示例

if name == "main": builder = DocsSiteBuilder( api_token=os.environ["GITBOOK_API_TOKEN"], org_id="org_xxxxx" )
# Create main docs site
space = builder.create_docs_site(
    title="Product Documentation",
    description="Complete product documentation",
    visibility="public",
    branding={
        "styling": {
            "primaryColor": "#0066FF",
            "font": "Inter"
        },
        "themes": {
            "default": "light",
            "toggeable": True
        }
    }
)

# Set up versions
builder.setup_versioned_docs(space["id"], [
    {"title": "v1.0", "slug": "v1"},
    {"title": "v2.0", "slug": "v2", "primary": True},
    {"title": "Latest", "slug": "latest"}
])
undefined
if name == "main": builder = DocsSiteBuilder( api_token=os.environ["GITBOOK_API_TOKEN"], org_id="org_xxxxx" )
# 创建主文档站点
space = builder.create_docs_site(
    title="Product Documentation",
    description="Complete product documentation",
    visibility="public",
    branding={
        "styling": {
            "primaryColor": "#0066FF",
            "font": "Inter"
        },
        "themes": {
            "default": "light",
            "toggeable": True
        }
    }
)

# 设置多版本
builder.setup_versioned_docs(space["id"], [
    {"title": "v1.0", "slug": "v1"},
    {"title": "v2.0", "slug": "v2", "primary": True},
    {"title": "Latest", "slug": "latest"}
])
undefined

Example 2: Content Migration Tool

示例2:内容迁移工具

python
#!/usr/bin/env python3
"""content_migration.py - Migrate content to GitBook"""

import os
from pathlib import Path
import re
import shutil

class ContentMigrator:
    """Migrate content from various formats to GitBook."""

    def __init__(self, source_path, output_path):
        self.source_path = Path(source_path)
        self.output_path = Path(output_path)

    def migrate_mkdocs(self):
        """
        Migrate MkDocs project to GitBook format.
        """
        # Copy markdown files
        docs_src = self.source_path / "docs"
        if not docs_src.exists():
            docs_src = self.source_path

        shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)

        # Convert mkdocs.yml nav to SUMMARY.md
        mkdocs_config = self.source_path / "mkdocs.yml"
        if mkdocs_config.exists():
            summary = self._convert_mkdocs_nav(mkdocs_config)
            (self.output_path / "SUMMARY.md").write_text(summary)

        # Create .gitbook.yaml
        gitbook_config = """
root: ./

structure:
  readme: README.md
  summary: SUMMARY.md
"""
        (self.output_path / ".gitbook.yaml").write_text(gitbook_config)

        print(f"Migrated MkDocs project to: {self.output_path}")

    def _convert_mkdocs_nav(self, mkdocs_path):
        """Convert MkDocs nav to SUMMARY.md format."""
        import yaml

        with open(mkdocs_path) as f:
            config = yaml.safe_load(f)

        nav = config.get("nav", [])
        lines = ["# Summary\n"]

        def process_nav(items, indent=0):
            for item in items:
                if isinstance(item, dict):
                    for title, value in item.items():
                        if isinstance(value, str):
                            lines.append(f"{'  ' * indent}* [{title}]({value})")
                        elif isinstance(value, list):
                            lines.append(f"\n{'  ' * indent}## {title}\n")
                            process_nav(value, indent + 1)
                elif isinstance(item, str):
                    lines.append(f"{'  ' * indent}* [{item}]({item})")

        process_nav(nav)
        return "\n".join(lines)

    def migrate_docusaurus(self):
        """Migrate Docusaurus project to GitBook format."""
        docs_src = self.source_path / "docs"

        # Copy docs
        shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)

        # Convert sidebars.js to SUMMARY.md
        sidebars = self.source_path / "sidebars.js"
        if sidebars.exists():
            # Basic conversion (would need proper JS parsing for complex sidebars)
            summary = self._generate_summary_from_files()
            (self.output_path / "SUMMARY.md").write_text(summary)

        # Create .gitbook.yaml
        (self.output_path / ".gitbook.yaml").write_text("""
root: ./

structure:
  readme: intro.md
  summary: SUMMARY.md
""")

        print(f"Migrated Docusaurus project to: {self.output_path}")

    def _generate_summary_from_files(self):
        """Generate SUMMARY.md from file structure."""
        lines = ["# Summary\n"]

        for md_file in sorted(self.output_path.rglob("*.md")):
            if md_file.name == "SUMMARY.md":
                continue

            relative = md_file.relative_to(self.output_path)
            title = self._extract_title(md_file) or md_file.stem

            depth = len(relative.parts) - 1
            lines.append(f"{'  ' * depth}* [{title}]({relative})")

        return "\n".join(lines)

    def _extract_title(self, md_path):
        """Extract title from markdown file."""
        content = md_path.read_text()

        # Check for frontmatter title
        if content.startswith("---"):
            match = re.search(r"title:\s*[\"']?(.+?)[\"']?\n", content)
            if match:
                return match.group(1)

        # Check for H1
        match = re.search(r"^#\s+(.+)$", content, re.MULTILINE)
        if match:
            return match.group(1)

        return None

    def fix_links(self):
        """Fix relative links for GitBook."""
        for md_file in self.output_path.rglob("*.md"):
            content = md_file.read_text()

            # Fix relative links without .md extension
            content = re.sub(
                r'\[([^\]]+)\]\((?!http)([^)]+)(?<!\.md)\)',
                r'[\1](\2.md)',
                content
            )

            # Fix image paths
            content = re.sub(
                r'!\[([^\]]*)\]\((?!http)\.\./',
                r'![\1](/',
                content
            )

            md_file.write_text(content)

        print("Fixed links in all markdown files")
python
#!/usr/bin/env python3
"""content_migration.py - 将内容迁移到GitBook"""

import os
from pathlib import Path
import re
import shutil

class ContentMigrator:
    """将各种格式的内容迁移到GitBook。"""

    def __init__(self, source_path, output_path):
        self.source_path = Path(source_path)
        self.output_path = Path(output_path)

    def migrate_mkdocs(self):
        """
        将MkDocs项目迁移到GitBook格式。
        """
        # 复制Markdown文件
        docs_src = self.source_path / "docs"
        if not docs_src.exists():
            docs_src = self.source_path

        shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)

        # 将mkdocs.yml导航转换为SUMMARY.md
        mkdocs_config = self.source_path / "mkdocs.yml"
        if mkdocs_config.exists():
            summary = self._convert_mkdocs_nav(mkdocs_config)
            (self.output_path / "SUMMARY.md").write_text(summary)

        # 创建.gitbook.yaml
        gitbook_config = """
root: ./

structure:
  readme: README.md
  summary: SUMMARY.md
"""
        (self.output_path / ".gitbook.yaml").write_text(gitbook_config)

        print(f"Migrated MkDocs project to: {self.output_path}")

    def _convert_mkdocs_nav(self, mkdocs_path):
        """将MkDocs导航转换为SUMMARY.md格式。"""
        import yaml

        with open(mkdocs_path) as f:
            config = yaml.safe_load(f)

        nav = config.get("nav", [])
        lines = ["# Summary\n"]

        def process_nav(items, indent=0):
            for item in items:
                if isinstance(item, dict):
                    for title, value in item.items():
                        if isinstance(value, str):
                            lines.append(f"{'  ' * indent}* [{title}]({value})")
                        elif isinstance(value, list):
                            lines.append(f"\n{'  ' * indent}## {title}\n")
                            process_nav(value, indent + 1)
                elif isinstance(item, str):
                    lines.append(f"{'  ' * indent}* [{item}]({item})")

        process_nav(nav)
        return "\n".join(lines)

    def migrate_docusaurus(self):
        """
        将Docusaurus项目迁移到GitBook格式。
        """
        docs_src = self.source_path / "docs"

        # 复制文档
        shutil.copytree(docs_src, self.output_path, dirs_exist_ok=True)

        # 将sidebars.js转换为SUMMARY.md
        sidebars = self.source_path / "sidebars.js"
        if sidebars.exists():
            # 基础转换(复杂侧边栏需要专门的JS解析)
            summary = self._generate_summary_from_files()
            (self.output_path / "SUMMARY.md").write_text(summary)

        # 创建.gitbook.yaml
        (self.output_path / ".gitbook.yaml").write_text("""
root: ./

structure:
  readme: intro.md
  summary: SUMMARY.md
""")

        print(f"Migrated Docusaurus project to: {self.output_path}")

    def _generate_summary_from_files(self):
        """根据文件结构生成SUMMARY.md。"""
        lines = ["# Summary\n"]

        for md_file in sorted(self.output_path.rglob("*.md")):
            if md_file.name == "SUMMARY.md":
                continue

            relative = md_file.relative_to(self.output_path)
            title = self._extract_title(md_file) or md_file.stem

            depth = len(relative.parts) - 1
            lines.append(f"{'  ' * depth}* [{title}]({relative})")

        return "\n".join(lines)

    def _extract_title(self, md_path):
        """从Markdown文件中提取标题。"""
        content = md_path.read_text()

        # 检查前置元数据中的标题
        if content.startswith("---"):
            match = re.search(r"title:\s*[\"']?(.+?)[\"']?\n", content)
            if match:
                return match.group(1)

        # 检查一级标题
        match = re.search(r"^#\s+(.+)$", content, re.MULTILINE)
        if match:
            return match.group(1)

        return None

    def fix_links(self):
        """修复GitBook的相对链接。"""
        for md_file in self.output_path.rglob("*.md"):
            content = md_file.read_text()

            # 修复不带.md扩展名的相对链接
            content = re.sub(
                r'\[([^\]]+)\]\((?!http)([^)]+)(?<!\.md)\)',
                r'[\1](\2.md)',
                content
            )

            # 修复图片路径
            content = re.sub(
                r'!\[([^\]]*)\]\((?!http)\.\./',
                r'![\1](/',
                content
            )

            md_file.write_text(content)

        print("Fixed links in all markdown files")

Example usage

使用示例

if name == "main": migrator = ContentMigrator( source_path="./mkdocs-project", output_path="./gitbook-docs" )
migrator.migrate_mkdocs()
migrator.fix_links()
undefined
if name == "main": migrator = ContentMigrator( source_path="./mkdocs-project", output_path="./gitbook-docs" )
migrator.migrate_mkdocs()
migrator.fix_links()
undefined

Example 3: Documentation Analytics

示例3:文档分析工具

python
#!/usr/bin/env python3
"""docs_analytics.py - GitBook documentation analytics"""

import os
from datetime import datetime, timedelta
import json

class DocsAnalytics:
    """Analyze GitBook documentation usage."""

    def __init__(self, api_token):
        self.client = GitBookClient(api_token)

    def get_space_stats(self, space_id):
        """Get statistics for a space."""
        space = self.client.get_space(space_id)
        content = self.client.get_space_content(space_id)

        # Count pages
        def count_pages(pages):
            count = len(pages)
            for page in pages:
                if "pages" in page:
                    count += count_pages(page["pages"])
            return count

        page_count = count_pages(content.get("pages", []))

        # Get variants
        variants = self.client.list_variants(space_id)

        return {
            "space_id": space_id,
            "title": space.get("title"),
            "visibility": space.get("visibility"),
            "page_count": page_count,
            "variant_count": len(variants.get("items", [])),
            "created_at": space.get("createdAt"),
            "updated_at": space.get("updatedAt")
        }

    def audit_content(self, space_id):
        """Audit content for issues."""
        content = self.client.get_space_content(space_id)
        issues = []

        def check_pages(pages, path=""):
            for page in pages:
                page_path = f"{path}/{page.get('slug', 'unknown')}"

                # Check for missing titles
                if not page.get("title"):
                    issues.append({
                        "type": "missing_title",
                        "path": page_path
                    })

                # Check for empty pages
                if not page.get("document"):
                    issues.append({
                        "type": "empty_page",
                        "path": page_path
                    })

                # Recurse into child pages
                if "pages" in page:
                    check_pages(page["pages"], page_path)

        check_pages(content.get("pages", []))
        return issues

    def generate_report(self, org_id):
        """Generate analytics report for organization."""
        spaces = self.client.list_spaces(org_id)

        report = {
            "generated_at": datetime.now().isoformat(),
            "org_id": org_id,
            "summary": {
                "total_spaces": 0,
                "total_pages": 0,
                "public_spaces": 0,
                "private_spaces": 0
            },
            "spaces": []
        }

        for space in spaces.get("items", []):
            stats = self.get_space_stats(space["id"])
            report["spaces"].append(stats)

            report["summary"]["total_spaces"] += 1
            report["summary"]["total_pages"] += stats["page_count"]

            if stats["visibility"] == "public":
                report["summary"]["public_spaces"] += 1
            else:
                report["summary"]["private_spaces"] += 1

        return report
python
#!/usr/bin/env python3
"""docs_analytics.py - GitBook文档使用分析"""

import os
from datetime import datetime, timedelta
import json

class DocsAnalytics:
    """分析GitBook文档的使用情况。"""

    def __init__(self, api_token):
        self.client = GitBookClient(api_token)

    def get_space_stats(self, space_id):
        """获取空间统计数据。"""
        space = self.client.get_space(space_id)
        content = self.client.get_space_content(space_id)

        # 统计页面数量
        def count_pages(pages):
            count = len(pages)
            for page in pages:
                if "pages" in page:
                    count += count_pages(page["pages"])
            return count

        page_count = count_pages(content.get("pages", []))

        # 获取版本变体
        variants = self.client.list_variants(space_id)

        return {
            "space_id": space_id,
            "title": space.get("title"),
            "visibility": space.get("visibility"),
            "page_count": page_count,
            "variant_count": len(variants.get("items", [])),
            "created_at": space.get("createdAt"),
            "updated_at": space.get("updatedAt")
        }

    def audit_content(self, space_id):
        """检查内容中的问题。"""
        content = self.client.get_space_content(space_id)
        issues = []

        def check_pages(pages, path=""):
            for page in pages:
                page_path = f"{path}/{page.get('slug', 'unknown')}"

                # 检查是否缺少标题
                if not page.get("title"):
                    issues.append({
                        "type": "missing_title",
                        "path": page_path
                    })

                # 检查是否为空页面
                if not page.get("document"):
                    issues.append({
                        "type": "empty_page",
                        "path": page_path
                    })

                # 递归检查子页面
                if "pages" in page:
                    check_pages(page["pages"], page_path)

        check_pages(content.get("pages", []))
        return issues

    def generate_report(self, org_id):
        """生成组织的文档分析报告。"""
        spaces = self.client.list_spaces(org_id)

        report = {
            "generated_at": datetime.now().isoformat(),
            "org_id": org_id,
            "summary": {
                "total_spaces": 0,
                "total_pages": 0,
                "public_spaces": 0,
                "private_spaces": 0
            },
            "spaces": []
        }

        for space in spaces.get("items", []):
            stats = self.get_space_stats(space["id"])
            report["spaces"].append(stats)

            report["summary"]["total_spaces"] += 1
            report["summary"]["total_pages"] += stats["page_count"]

            if stats["visibility"] == "public":
                report["summary"]["public_spaces"] += 1
            else:
                report["summary"]["private_spaces"] += 1

        return report

Example usage

使用示例

if name == "main": analytics = DocsAnalytics(os.environ["GITBOOK_API_TOKEN"])
# Get org report
report = analytics.generate_report("org_xxxxx")

print(f"Documentation Analytics Report")
print(f"{'='*50}")
print(f"Total Spaces: {report['summary']['total_spaces']}")
print(f"Total Pages: {report['summary']['total_pages']}")
print(f"Public: {report['summary']['public_spaces']}")
print(f"Private: {report['summary']['private_spaces']}")

print(f"\nSpaces:")
for space in report["spaces"]:
    print(f"  - {space['title']}: {space['page_count']} pages")

# Save report
with open("docs_report.json", "w") as f:
    json.dump(report, f, indent=2)
undefined
if name == "main": analytics = DocsAnalytics(os.environ["GITBOOK_API_TOKEN"])
# 获取组织报告
report = analytics.generate_report("org_xxxxx")

print(f"Documentation Analytics Report")
print(f"{'='*50}")
print(f"Total Spaces: {report['summary']['total_spaces']}")
print(f"Total Pages: {report['summary']['total_pages']}")
print(f"Public: {report['summary']['public_spaces']}")
print(f"Private: {report['summary']['private_spaces']}")

print(f"\nSpaces:")
for space in report["spaces"]:
    print(f"  - {space['title']}: {space['page_count']} pages")

# 保存报告
with open("docs_report.json", "w") as f:
    json.dump(report, f, indent=2)
undefined

Integration Examples

集成示例

GitHub Actions for Git Sync

GitHub Actions实现Git同步

yaml
undefined
yaml
undefined

.github/workflows/gitbook-sync.yml

.github/workflows/gitbook-sync.yml

name: Sync to GitBook
on: push: branches: [main] paths: - 'docs/**' - 'SUMMARY.md'
jobs: sync: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4
  - name: Validate Structure
    run: |
      # Check required files exist
      test -f docs/README.md || echo "Missing docs/README.md"
      test -f docs/SUMMARY.md || echo "Missing docs/SUMMARY.md"

      # Check for broken links
      python3 << 'EOF'
      import re
      from pathlib import Path

      summary = Path("docs/SUMMARY.md").read_text()
      links = re.findall(r'\[.*?\]\((.*?\.md)\)', summary)

      for link in links:
          path = Path("docs") / link
          if not path.exists():
              print(f"Broken link: {link}")
              exit(1)

      print("All links valid!")
      EOF

  - name: Notify on Success
    if: success()
    run: |
      echo "Documentation synced successfully!"
      # GitBook automatically pulls from connected repo
undefined
name: Sync to GitBook
on: push: branches: [main] paths: - 'docs/**' - 'SUMMARY.md'
jobs: sync: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4
  - name: Validate Structure
    run: |
      # 检查必要文件是否存在
      test -f docs/README.md || echo "Missing docs/README.md"
      test -f docs/SUMMARY.md || echo "Missing docs/SUMMARY.md"

      # 检查是否有失效链接
      python3 << 'EOF'
      import re
      from pathlib import Path

      summary = Path("docs/SUMMARY.md").read_text()
      links = re.findall(r'\[.*?\]\((.*?\.md)\)', summary)

      for link in links:
          path = Path("docs") / link
          if not path.exists():
              print(f"Broken link: {link}")
              exit(1)

      print("All links valid!")
      EOF

  - name: Notify on Success
    if: success()
    run: |
      echo "Documentation synced successfully!"
      # GitBook会自动从关联仓库拉取更新
undefined

Slack Notification for Updates

Slack通知文档更新

python
#!/usr/bin/env python3
"""slack_notify.py - Notify Slack of GitBook updates"""

import os
import requests
from datetime import datetime, timedelta

def notify_docs_update(space_title, update_type, details):
    """Send Slack notification for docs update."""
    webhook_url = os.environ["SLACK_WEBHOOK_URL"]

    message = {
        "blocks": [
            {
                "type": "header",
                "text": {
                    "type": "plain_text",
                    "text": f"Documentation Update: {space_title}"
                }
            },
            {
                "type": "section",
                "fields": [
                    {
                        "type": "mrkdwn",
                        "text": f"*Type:*\n{update_type}"
                    },
                    {
                        "type": "mrkdwn",
                        "text": f"*Time:*\n{datetime.now().strftime('%Y-%m-%d %H:%M')}"
                    }
                ]
            },
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": f"*Details:*\n{details}"
                }
            }
        ]
    }

    response = requests.post(webhook_url, json=message)
    return response.status_code == 200
python
#!/usr/bin/env python3
"""slack_notify.py - 文档更新时发送Slack通知"""

import os
import requests
from datetime import datetime, timedelta

def notify_docs_update(space_title, update_type, details):
    """发送Slack通知告知文档更新。"""
    webhook_url = os.environ["SLACK_WEBHOOK_URL"]

    message = {
        "blocks": [
            {
                "type": "header",
                "text": {
                    "type": "plain_text",
                    "text": f"Documentation Update: {space_title}"
                }
            },
            {
                "type": "section",
                "fields": [
                    {
                        "type": "mrkdwn",
                        "text": f"*Type:*\n{update_type}"
                    },
                    {
                        "type": "mrkdwn",
                        "text": f"*Time:*\n{datetime.now().strftime('%Y-%m-%d %H:%M')}"
                    }
                ]
            },
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": f"*Details:*\n{details}"
                }
            }
        ]
    }

    response = requests.post(webhook_url, json=message)
    return response.status_code == 200

Best Practices

最佳实践

1. Structure Content Properly

1. 合理组织内容结构

markdown
undefined
markdown
undefined

Good structure

良好的结构

docs/ ├── README.md # Landing page ├── SUMMARY.md # Navigation ├── getting-started/ │ ├── README.md # Section intro │ ├── installation.md │ └── quickstart.md └── guides/ ├── README.md └── ...
undefined
docs/ ├── README.md # 首页 ├── SUMMARY.md # 导航目录 ├── getting-started/ │ ├── README.md # 章节介绍 │ ├── installation.md │ └── quickstart.md └── guides/ ├── README.md └── ...
undefined

2. Use Meaningful Slugs

2. 使用有意义的路径别名

markdown
undefined
markdown
undefined

SUMMARY.md - Good slugs

SUMMARY.md - 良好的路径别名

  • Installation Guide
  • API Reference
  • Installation Guide
  • API Reference

Avoid

避免以下写法

  • Page 1
  • Untitled
undefined
  • Page 1
  • Untitled
undefined

3. Maintain Version Consistency

3. 保持版本一致性

python
undefined
python
undefined

Use consistent version naming

使用统一的版本命名规则

versions = [ {"title": "v1.0", "slug": "v1"}, {"title": "v2.0", "slug": "v2"}, {"title": "Latest", "slug": "latest"} ]
undefined
versions = [ {"title": "v1.0", "slug": "v1"}, {"title": "v2.0", "slug": "v2"}, {"title": "Latest", "slug": "latest"} ]
undefined

4. Validate Before Publish

4. 发布前验证内容

python
def validate_docs(docs_path):
    """Validate docs before publishing."""
    issues = []

    # Check SUMMARY.md exists
    if not (docs_path / "SUMMARY.md").exists():
        issues.append("Missing SUMMARY.md")

    # Check all linked files exist
    # Check for broken internal links
    # Check image paths

    return issues
python
def validate_docs(docs_path):
    """发布前验证文档。"""
    issues = []

    # 检查SUMMARY.md是否存在
    if not (docs_path / "SUMMARY.md").exists():
        issues.append("Missing SUMMARY.md")

    # 检查所有链接的文件是否存在
    # 检查内部失效链接
    # 检查图片路径

    return issues

Troubleshooting

故障排除

Common Issues

常见问题

Issue: 401 Unauthorized
bash
undefined
问题:401 Unauthorized(未授权)
bash
undefined

Verify token

验证令牌有效性

curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user"
curl -s -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/user"

Regenerate token at:

在以下地址重新生成令牌:


**Issue: Git sync not updating**
```bash

**问题:Git同步未更新**
```bash

Check Git connection in GitBook space settings

在GitBook空间设置中检查Git连接

Verify branch name matches

验证分支名称是否匹配

Check for merge conflicts

检查是否存在合并冲突

Force resync via API

通过API强制重新同步

curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/spaces/SPACE_ID/git/sync"

**Issue: Broken links after migration**
```python
curl -s -X POST -H "Authorization: Bearer $GITBOOK_API_TOKEN"
"https://api.gitbook.com/v1/spaces/SPACE_ID/git/sync"

**问题:迁移后链接失效**
```python

Fix relative links

修复相对链接

import re
content = path.read_text()
import re
content = path.read_text()

Add .md extension to links

为链接添加.md扩展名

content = re.sub( r'[([^]]+)]((?!http)([^)]+)(?<!.md))', r'\1', content )

**Issue: Images not displaying**
```markdown
<!-- Use absolute paths from root -->
![Image](/assets/image.png)

<!-- Or relative from current file -->
![Image](./images/image.png)
content = re.sub( r'[([^]]+)]((?!http)([^)]+)(?<!.md))', r'\1', content )

**问题:图片无法显示**
```markdown
<!-- 使用从根目录开始的绝对路径 -->
![Image](/assets/image.png)

<!-- 或使用相对于当前文件的路径 -->
![Image](./images/image.png)

Version History

版本历史

  • 1.0.0 (2026-01-17): Initial release
    • Spaces management API
    • Collections and variants
    • Git synchronization
    • Team collaboration
    • Custom domains and branding
    • Content migration tools
    • Analytics and reporting
    • GitHub Actions integration
    • Best practices and troubleshooting
  • 1.0.0 (2026-01-17): 初始版本
    • 空间管理API
    • 合集与版本变体
    • Git同步
    • 团队协作
    • 自定义域名与品牌
    • 内容迁移工具
    • 分析与报告
    • GitHub Actions集成
    • 最佳实践与故障排除

Resources

参考资源


Publish beautiful documentation with GitBook - spaces, collections, and seamless Git integration!

使用GitBook发布美观的文档——空间、合集与无缝Git集成!