build-integration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBuild a GitBook Integration
构建GitBook集成
A skill for building integrations on GitBook's developer platform: apps that run inside GitBook itself. An integration can render custom blocks in the editor, show configuration UI, listen to events (content updated, Git sync completed, space viewed), authenticate against external services with OAuth, and talk to anything over HTTP.
This skill covers the integration lifecycle — scaffold, code, develop, publish. For creating or restructuring the docs site an integration might be installed into, defer to ; for authoring page content, defer to .
configure-sitewrite-docs本技能用于在GitBook开发者平台上构建集成:即运行在GitBook内部的应用。集成可在编辑器中渲染自定义区块、显示配置UI、监听事件(内容更新、Git同步完成、空间浏览)、通过OAuth向外部服务认证,以及通过HTTP与任意服务通信。
本技能涵盖集成的完整生命周期——搭建框架、编码、开发、发布。若需创建或重构集成所安装的文档站点,请使用技能;若需编写页面内容,请使用技能。
configure-sitewrite-docsWhat an integration is (mental model)
集成是什么(心智模型)
An integration is a small TypeScript app executed by GitBook's runtime — not a script injected into pages, and not code running on the user's server. Three consequences shape everything else:
- Rendering happens on GitBook's backend. Your component's function runs server-side on every interaction and returns ContentKit markup (a JSX-like UI description). There is no client-side React tree you control, no DOM access, and UI updates flow through the action → new state → re-render loop.
render - You cannot inject JavaScript into a site. The and
site:script:injectscopes you'll see in GitBook-owned integrations are internal-only. If the user's plan amounts to "add a script tag to their docs", stop and say so early — the supported paths are custom blocks, webframes, and events.site:script:cookies - Local development is a proxy, not a server you visit. routes the installed integration's traffic to your machine. You never open the dev server's port in a browser; you interact with the integration inside app.gitbook.com.
gitbook dev
集成是由GitBook运行时执行的小型TypeScript应用——并非注入页面的脚本,也不是运行在用户服务器上的代码。这带来了三个关键影响,决定了集成开发的所有特性:
- 渲染在GitBook后端进行。组件的函数在每次交互时都在服务器端运行,并返回ContentKit标记(类JSX的UI描述)。你无法控制客户端React树,也无法访问DOM,UI更新遵循“动作→新状态→重新渲染”的循环。
render - 无法向站点注入JavaScript。你在GitBook官方集成中看到的和
site:script:inject权限范围仅内部可用。如果用户的需求是“向文档添加脚本标签”,请尽早告知无法实现——支持的方案包括自定义区块、网页框架和事件处理。site:script:cookies - 本地开发是代理模式,而非直接访问服务器。会将已安装集成的流量路由到你的本地机器。你无需在浏览器中打开开发服务器端口,而是在app.gitbook.com内部与集成交互。
gitbook dev
The project
项目结构
gitbook newmy-integration/
├── gitbook-manifest.yaml # identity, scopes, blocks, configuration schema
├── .gitbook-dev.yaml # local dev config (generated by `gitbook dev`)
├── package.json
└── src/
└── index.tsx # entry file — default-exports createIntegration()The entry file (whatever in the manifest points to) default-exports :
script:createIntegration({ fetch, components, events })tsx
import { createIntegration, createComponent } from '@gitbook/runtime';
const helloBlock = createComponent({
componentId: 'hello-world', // must match a block id in the manifest
initialState: { message: 'Say hello!' },
action: async (element, action, context) => {
switch (action.action) {
case 'say':
return { state: { message: 'Hello world' } };
default:
return {};
}
},
render: async (element, context) => (
<block>
<button label={element.state.message} onPress={{ action: 'say' }} />
</block>
),
});
export default createIntegration({
components: [helloBlock],
events: {
space_content_updated: async (event, context) => {
// react to content changes
},
},
});A custom block only appears in the editor's insert palette (⌘ + /) if it is declared in both places: in the code and a entry in the manifest whose matches the . Forgetting one half is the most common "my block doesn't show up" cause.
createComponentblocks:idcomponentIdgitbook newmy-integration/
├── gitbook-manifest.yaml # identity, scopes, blocks, configuration schema
├── .gitbook-dev.yaml # local dev config (generated by `gitbook dev`)
├── package.json
└── src/
└── index.tsx # entry file — default-exports createIntegration()入口文件(即清单中指向的文件)需默认导出:
script:createIntegration({ fetch, components, events })tsx
import { createIntegration, createComponent } from '@gitbook/runtime';
const helloBlock = createComponent({
componentId: 'hello-world', // must match a block id in the manifest
initialState: { message: 'Say hello!' },
action: async (element, action, context) => {
switch (action.action) {
case 'say':
return { state: { message: 'Hello world' } };
default:
return {};
}
},
render: async (element, context) => (
<block>
<button label={element.state.message} onPress={{ action: 'say' }} />
</block>
),
});
export default createIntegration({
components: [helloBlock],
events: {
space_content_updated: async (event, context) => {
// react to content changes
},
},
});自定义区块只有在两处都进行声明时才会出现在编辑器的插入面板(⌘ + /)中:代码中的,以及清单中条目里与匹配的内容。遗漏其中一处是“我的区块不显示”问题最常见的原因。
createComponentblocks:idcomponentIdThe manifest, briefly
清单简介
gitbook-manifest.yamlnameacme-changelogtesttitledescriptionorganizationvisibilityscopesscriptThe manifest also declares , installer-facing (account-level and site-level property schemas rendered as a settings form), and (e.g. , loaded at publish time — use so sees your ).
blocksconfigurationssecretsCLIENT_ID: ${{ env.CLIENT_ID }}dotenv-cligitbook publish.envFull field-by-field schema, scope list, and configuration property types: . Read it whenever you're editing the manifest beyond the basics.
references/manifest.mdgitbook-manifest.yamlnameacme-changelogtesttitledescriptionorganizationvisibilityscopesscript清单还会声明、面向安装者的(账户级和站点级属性 schema,会渲染为设置表单),以及(例如,在发布时加载——请使用确保能读取你的文件)。
blocksconfigurationssecretsCLIENT_ID: ${{ env.CLIENT_ID }}dotenv-cligitbook publish.env完整的字段schema、权限范围列表和配置属性类型请参考。当你对清单的编辑超出基础内容时,请务必查阅此文档。
references/manifest.mdThe development loop
开发流程
The loop has a non-obvious order — publish comes before local development:
- Prerequisites. Node 18+, a personal access token from https://app.gitbook.com/account/developer, and the CLI: , then
npm install @gitbook/cli -g(orgitbook auth). If a token needs to be pasted into the conversation, export it to the environment and never echo it back or commit it.gitbook auth --token=<token> - Scaffold. — prompts for name, title, organization, and scopes.
gitbook new <dir> - Publish once. in the project root. This registers the integration (private by default) and prints an install link.
gitbook publish - Install it into at least one space or site via that link. Local dev doesn't work until it's installed somewhere.
- Develop. starts the proxy: all traffic for the installed integration is served from your local code instead of the published version. Interact with it in the GitBook editor, not at the server URL. UI changes need a browser refresh; disable browser caching for a smoother loop. Logs surface in the browser console or your terminal depending on where the code runs — check both before concluding logging is broken.
gitbook dev - Re-publish with whenever you want the hosted version updated.
gitbook publishremoves it.gitbook unpublish <name>
CLI command reference (including and ): .
gitbook whoamigitbook openapi publishreferences/manifest.md开发流程的顺序有些特殊——先发布再进行本地开发:
- 前置条件。Node 18+版本、从https://app.gitbook.com/account/developer获取的个人访问令牌,以及GitBook CLI:执行安装CLI,然后运行
npm install @gitbook/cli -g(或gitbook auth)进行认证。如果需要在对话中粘贴令牌,请将其导出到环境变量中,切勿回显或提交令牌。gitbook auth --token=<token> - 搭建框架。执行——系统会提示输入名称、标题、组织和权限范围。
gitbook new <dir> - 首次发布。在项目根目录执行。这会注册集成(默认私有)并打印安装链接。
gitbook publish - 安装集成。通过上述链接将集成安装到至少一个空间或站点中。只有安装完成后,本地开发才能正常工作。
- 开发调试。执行启动代理:已安装集成的所有流量都会路由到你的本地代码,而非已发布版本。请在GitBook编辑器中与集成交互,而非访问服务器URL。UI变更需要刷新浏览器;建议禁用浏览器缓存以获得更流畅的开发体验。日志会根据代码运行位置显示在浏览器控制台或终端中——在判断日志功能异常前,请检查这两个位置。
gitbook dev - 重新发布。每当你想要更新托管版本时,执行。
gitbook publish命令可移除已发布的集成。gitbook unpublish <name>
CLI命令参考(包括和)请查阅。
gitbook whoamigitbook openapi publishreferences/manifest.mdRuntime: fetch, events, environment, OAuth
运行时:fetch、事件、环境、OAuth
Details and full tables live in — read it when writing event handlers, OAuth flows, or anything touching . The essentials:
references/runtime.mdcontext.environment- handles incoming HTTP requests to the integration's public endpoint using standard Fetch API
fetch/Requestobjects. Outgoing HTTP is plainResponsetoo.fetch - maps event names (
events,installation_setup,space_installation_setup,space_view,ui_render,space_content_updated,space_visibility_updated,space_gitsync_started) to handlers. Some events require matching scopes.space_gitsync_completed - exposes
context.environment,apiEndpoint, installation info (space, status, per-installationapiTokensvalues entered by the installer),configuration, and public URLs (secrets).environment.integration.urls.publicEndpoint - OAuth against an external provider is a fixed pattern: a -type configuration property whose
buttonroutes to acallback_urlin your fetch handler, with client id/secret coming fromcreateOAuthHandler({...}). Don't hand-roll the redirect/token exchange.secrets - Calling the GitBook API from inside the integration: use (an authenticated
context.apiclient) rather than constructing your own client from raw tokens.@gitbook/api
详细信息和完整表格请参考——当你编写事件处理程序、OAuth流程或任何涉及的代码时,请务必查阅此文档。核心要点如下:
references/runtime.mdcontext.environment- 使用标准Fetch API的
fetch/Request对象处理发送到集成公共端点的HTTP请求。对外发送HTTP请求也使用普通的Response方法。fetch - 将事件名称(
events、installation_setup、space_installation_setup、space_view、ui_render、space_content_updated、space_visibility_updated、space_gitsync_started)映射到对应的处理程序。部分事件需要匹配相应的权限范围。space_gitsync_completed - 暴露
context.environment、apiEndpoint、安装信息(空间、状态、安装者输入的每安装实例apiTokens值)、configuration以及公共URL(secrets)。environment.integration.urls.publicEndpoint - OAuth 对接外部服务提供商遵循固定模式:使用类型的配置属性,其
button路由到你的fetch处理程序中的callback_url,客户端ID/密钥来自createOAuthHandler({...})。请勿手动实现重定向/令牌交换逻辑。secrets - 从集成内部调用GitBook API:请使用(已认证的
context.api客户端),而非使用原始令牌自行构建客户端。@gitbook/api
ContentKit: building the UI
ContentKit:构建UI
ContentKit is the component vocabulary can return: layout (, , , ), display (, , , , ), and interactive elements (, , , , , , , , ). Interactivity model in one line: inputs bind their value to a key; buttons dispatch actions; your reducer returns new state; GitBook re-renders.
renderblockvstackhstackdividerboxcardtextimagemarkdownbuttontextinputselectswitchcheckboxradiocodeblockwebframemodalstateactionRead before writing any component beyond a trivial button — it has the full prop tables plus the patterns that are hard to guess: dynamic state binding for live previews, webframe communication, modals with , persisting props with , link unfurling via + manifest patterns, and markdown code-block serialization of blocks.
references/contentkit.mdpostMessagereturnValue@editor.node.updateProps@link.unfurlurlUnfurlContentKit是函数可返回的组件集合:包括布局组件(、、、)、展示组件(、、、、)和交互组件(、、、、、、、、)。交互模式可概括为:输入组件将值绑定到键;按钮触发动作;你的 reducer返回新状态;GitBook重新渲染。
renderblockvstackhstackdividerboxcardtextimagemarkdownbuttontextinputselectswitchcheckboxradiocodeblockwebframemodalstateaction在编写除简单按钮外的任何组件之前,请查阅——该文档包含完整的属性表以及难以自行摸索的模式:实时预览的动态状态绑定、webframe的通信、带的模态框、使用持久化属性、通过 + 清单模式实现链接展开,以及区块的Markdown代码块序列化。
references/contentkit.mdpostMessagereturnValue@editor.node.updateProps@link.unfurlurlUnfurlPublishing and sharing
发布与分享
Visibility in the manifest controls reach:
- (default) — installable only by members of the owning org. Right for internal tools; stay here during development.
private - — installable by any org, but only via the shared install link. Right for sharing with specific customers or beta testers.
unlisted - — installable by anyone; required before submitting to the integration marketplace (which is a separate review process — see GitBook's "submit your app for review" docs).
public
Re-run after changing visibility. Before suggesting , sanity-check the manifest is presentable: , (Markdown, ≤2048 chars), (1600×800), , .
gitbook publishpubliciconsummarypreviewImagescategoriesexternalLinks清单中的字段控制集成的可访问范围:
visibility- (默认)——仅所属组织成员可安装。适用于内部工具;开发期间请保持此设置。
private - ——任意组织均可安装,但需通过共享的安装链接。适用于与特定客户或测试人员分享。
unlisted - ——任何人都可安装;提交至集成应用市场前必须设置为此值(应用市场提交需单独审核流程——请查阅GitBook的“提交你的应用进行审核”文档)。
public
修改后需重新执行。在建议设置为之前,请检查清单内容是否完整规范:包括、(Markdown格式,≤2048字符)、(尺寸1600×800)、和。
visibilitygitbook publishpubliciconsummarypreviewImagescategoriesexternalLinksWorking style
开发建议
- Scaffold with the CLI rather than by hand when starting fresh — wires up the manifest, TypeScript config, and
gitbook newversions correctly.@gitbook/runtime - Trace a block's id chain (manifest ↔
blocks[].id) whenever a component misbehaves.componentId - Keep secrets out of the manifest file itself — always the indirection, never literal values.
${{ env.X }} - When the user's goal is content or site automation from outside GitBook (scripts hitting the REST API, CI pipelines), an integration may be the wrong tool — the plain API with a personal token is simpler. Integrations earn their keep when code must run inside GitBook: blocks, config UI, event reactions, OAuth on behalf of installers.
- 从零开始时使用CLI搭建框架而非手动创建——会正确配置清单、TypeScript配置和
gitbook new版本。@gitbook/runtime - 当组件出现异常时,追踪区块的ID链(清单↔
blocks[].id)。componentId - 切勿在清单文件中直接写入密钥——始终使用的间接引用方式,绝不使用明文值。
${{ env.X }} - 当用户的目标是从GitBook外部实现内容或站点自动化(如调用REST API的脚本、CI流水线)时,集成可能并非合适工具——使用带个人令牌的原生API更简单。只有当代码必须在GitBook内部运行时,集成才体现价值:例如自定义区块、配置UI、事件响应、代表安装者完成OAuth认证等场景。
References
参考文档
- — every
references/manifest.mdfield, all scopes, configuration property types, secrets, CLI command reference, installation/configuration flow.gitbook-manifest.yaml - —
references/runtime.md/createIntegration/createComponentsignatures, event catalog,createOAuthHandlershape, HTTP in and out.context.environment - — full component reference with props, built-in actions, and interactivity recipes (dynamic binding, webframes, modals, unfurling, markdown serialization).
references/contentkit.md
- ——包含
references/manifest.md的所有字段、权限范围列表、配置属性类型、密钥、CLI命令参考、安装/配置流程。gitbook-manifest.yaml - ——包含
references/runtime.md/createIntegration/createComponent的签名、事件目录、createOAuthHandler结构、HTTP输入输出处理。context.environment - ——包含完整的组件参考(带属性说明)、内置动作以及交互实现方案(动态绑定、网页框架、模态框、链接展开、Markdown序列化)。
references/contentkit.md