在 Astro Starlight 文档站中集成 Scalar API Reference:@scalar/starlight 插件完整上手指南
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
本文围绕@scalar/starlight插件的快速上手展开:它能把 Scalar 渲染的 API Reference 以插件注入的路由形式嵌入 Astro Starlight 文档站,让你在普通 Markdown 文档页旁边直接获得一份独立维护、可交互的 API 文档。读完本文,你将掌握插件的安装方式、最小配置、configuration/pathname/label/title四个核心选项、多 API Reference 的部署方法,以及插件在路由注入与侧边栏处理上的底层实现原理。
从文档页到 API Reference:这个插件解决什么问题
在 Starlight 文档站中,内容页存放在src/content/docs/目录下,并自动出现在侧边栏中。例如 getting-started.md 中描述的场景:
- 这是一个普通的 Starlight 文档页,位于
src/content/docs/guides/目录,会以Guides分组出现在侧边栏; - 侧边栏中紧随其下的API Reference条目并不是一个真实的文件,而是由
@scalar/starlight插件添加的,该插件同时负责在/api-reference路径提供 API Reference 页面。
也就是说,你不需要手工创建页面、复制粘贴ScalarComponent组件并维护路由——安装插件、传入一个 OpenAPI 文档地址,剩下的交给插件完成。这与@scalar/astro等集成方式相比,最大的差别是渲染结果会被包裹在 Starlight 的布局中,保留文档站原有的站点头部和侧边栏,视觉与导航体验完全一致。
安装与最小配置
在 Astro + Starlight 项目中安装插件:
npm install @scalar/starlight然后在astro.config.mjs中把插件挂到 Starlight 的plugins数组里,并指向你的 OpenAPI 文档:
// astro.config.mjs import { defineConfig } from 'astro/config' import starlight from '@astrojs/starlight' import { scalarStarlight } from '@scalar/starlight' export default defineConfig({ integrations: [ starlight({ title: 'My Docs', plugins: [ scalarStarlight({ // Scalar 的通用配置对象,url 指向 OpenAPI 文档 configuration: { url: '/openapi.json', }, }), ], }), ], })最小配置只需要一个configuration.url。默认情况下,API Reference 会从/api-reference路径提供。仓库中的 playground 实际配置与此一致,见 astro.config.mjs,它把url指向了https://registry.scalar.com/@scalar/apis/galaxy?format=json这份示例 OpenAPI 文档。
验证效果:文档站里“试一试”
按照 getting-started.md 中的指引,启动开发服务器后可以做两件事来验证集成是否成功:
- 从侧边栏点击API Reference入口,浏览器会打开
/api-reference路径,看到渲染完成的 Scalar API Reference(包含操作列表、请求示例、Schema 等交互能力); - 编辑任意文档页(例如
src/content/docs/guides/下的 Markdown 文件),保存后页面会热更新——普通文档内容与 API Reference 在同一套侧边栏结构下并存,互不干扰。
这个“编辑即更新”的行为来自 Starlight 的开发服务器热更新机制,而 API Reference 页面本身则依赖 Starlight 的客户端路由(详见下文实现原理一节)。
完整配置项
插件接收一个选项对象,类型定义在 plugin.ts 中,共四个字段:
| 选项 | 默认值 | 说明 |
|---|---|---|
configuration | —(必填) | Scalar 的通用配置对象,最重要的是url(OpenAPI 文档地址)或content(内联的 OpenAPI 内容),其余字段与 Scalar API Reference 的全局配置一致 |
pathname | '/api-reference' | API Reference 页面提供服务的路径 |
label | 'API Reference' | 侧边栏条目的显示文本 |
title | 取label的值 | API Reference 页面的<title>标题 |
注意一个约束:configuration会被序列化为 JSON 写入页面,因此函数类型的选项(自定义fetch、onLoaded回调、Scalar 插件等)不会生效——这与@scalar/astro的renderMode="client"行为一致,因为本插件正是基于它构建的(见 README.md)。
pathname需要以单个正斜杠开头且不能以正斜杠结尾。它先经过normalizePathname归一化处理(见 normalize-pathname.ts):拆分并过滤空段后重新拼接,因此'reference/'、'//docs//api/'这类写法会被统一规整为'/reference'、'/docs/api'。若归一化后解析为/(即站点根路径),插件会直接抛出错误,提示你改用/api-reference之类的子路径,避免与首页路由冲突。
自定义路由与侧边栏文本
guides/customize.md 给出了一个实用的自定义示例——更换服务路径并重命名侧边栏条目:
// astro.config.mjs scalarStarlight({ configuration: { url: '/openapi.json' }, pathname: '/reference', label: 'API', })效果:
- API Reference 不再位于
/api-reference,而是/reference; - 侧边栏条目由 “API Reference” 变为 “API”;
- 页面标题默认跟随
label,即 “API”,除非你显式传入title覆盖。
当传入pathname: 'reference/'时,测试用例(见 plugin.test.ts)会验证侧边栏链接被归一化为/reference,且自定义的title与归一化后的pathname被正确转发给路由集成。pathname既作为 Astro 路由模式,又作为 Starlight 侧边栏链接,因此两处必须使用同一套归一化逻辑,这正是normalizePathname被独立成模块、由插件与路由组件共用同一个文件的原因。
侧边栏的两种处理策略
插件在config:setup钩子中处理侧边栏(见 plugin.ts),行为取决于你的 Starlight 配置:
- 你显式定义了
sidebar:插件会保留现有条目,并在末尾追加{ label, link: pathname },例如已有的Guides分组之后多出 “API Reference” 入口。对应测试用例keeps existing sidebar entries验证了这一点; - 你没有定义
sidebar:Starlight 会基于src/content/docs/自动生成侧边栏。此时插件不会追加条目——如果强行追加,会把自动生成的侧边栏替换成只有一项的显式配置,从而隐藏你的其他所有页面。插件只会打印一条 warn 日志,提示你手动添加链接,例如:
sidebar: [{ label: 'API Reference', link: '/api-reference' }]这正是 playground 中 astro.config.mjs 显式声明sidebar: [{ label: 'Guides', autogenerate: { directory: 'guides' } }]的原因:显式侧边栏让插件可以安全地在其后追加 API Reference 入口。
多 API Reference:一个站点多份接口文档
如果产品有多个服务,可以在plugins数组中多次调用scalarStarlight,每次指定独立的pathname:
plugins: [ scalarStarlight({ pathname: '/reference/payments', label: 'Payments', configuration: { url: '/payments.json' } }), scalarStarlight({ pathname: '/reference/billing', label: 'Billing', configuration: { url: '/billing.json' } }), ]这样/reference/payments与/reference/billing会各自渲染一份 API Reference,侧边栏出现 “Payments” 与 “Billing” 两个入口。底层实现上,所有插件的实例会把各自的引用注册进一个以pathname为键的模块级注册表(见 integration.ts),由一个打包好的.astro组件在渲染时根据当前请求路径挑选对应的引用。
需要注意:
- 两个不同的引用共用同一个
pathname会抛出错误(“Two different API references are configured for …”),要求为每个引用分配独立路径;重复注册完全相同的引用则被允许,这兼容了开发服务器配置重载的场景; - 每个注入的 Astro 集成按
@scalar/starlight:${pathname}命名,避免 Astro 把多个集成误判为同一个而只保留第一个。
底层实现原理:路由注入、虚拟模块与客户端渲染
@scalar/starlight的运作链路可以分为三层(均位于 src 目录下):
Starlight 插件层(plugin.ts):在
config:setup钩子中做两件事——通过addIntegration注入路由集成、通过updateConfig追加侧边栏条目。由于 Starlight 插件本身无法直接注入路由,注入动作被委托给一个 Astro 集成完成。Astro 集成层(integration.ts):在
astro:config:setup钩子中调用injectRoute,把pathname模式指向包内自带的ScalarReference.astro组件;同时注册一个 Vite 虚拟模块插件,把注册表中的所有引用(标题 + 配置)序列化导出为virtual:scalar-starlight模块。因为注入的路由组件是打包产物、无法接收按实例区分的 props,所以通过虚拟模块在构建期传递数据是标准做法。渲染组件层(ScalarReference.astro):从虚拟模块读取
references注册表,剥离BASE_URL后用与插件相同的normalizePathname匹配出当前请求对应的引用;匹配失败时,若只有一个引用则回退到它,若有多个引用则直接抛错(避免静默渲染错误文档)。随后用<StarlightPage>包裹<ScalarComponent renderMode="client" configuration={configuration} />,并采用template: 'splash'让 API Reference 获得整行内容宽度(Scalar 自带操作侧边栏)。
renderMode="client"是这里的关键约束:Starlight 自带<ClientRouter />,导航在客户端进行,若采用静态渲染脚本,切页后脚本只会等到手动刷新才执行。客户端渲染模式保证了跨 Starlight 客户端导航时 API Reference 依然正常工作。
测试用例:行为如何被验证
仓库为插件编写了完整的 Vitest 测试(见 plugin.test.ts),覆盖了以下核心行为,可作为你配置时的行为契约:
- 插件名为
@scalar/starlight,且提供config:setup钩子; - 默认追加
{ label: 'API Reference', link: '/api-reference' }侧边栏条目; - 已有侧边栏条目会被保留,新条目追加在末尾;
- 自定义
pathname/label/title被正确归一化并转发,注入的集成按pathname命名; - 页面标题默认取
label; pathname归一化为/时抛出错误(包括'/'与'///'两种写法);- 未配置
sidebar时不修改配置、只记录一条 warn 日志; '//docs//api/'这类杂乱路径被归一化为/docs/api。
在仓库中本地体验
若想直接体验,可以查看本仓库中的 integrations/starlight/playground 目录:它是一套完整的 Astro + Starlight 演示站,包含astro.config.mjs、src/content.config.ts以及src/content/docs/下的文档页(index.mdx、guides/getting-started.md、guides/customize.md)。对照 getting-started.md 与 customize.md 两篇示例文档,可以直观看到“普通文档页 + 插件注入的 API Reference”在真实项目中的组织方式。
完整选项列表与注意事项以 integrations/starlight/README.md 为准,插件的类型定义与实现细节可进一步阅读 plugin.ts、integration.ts 与 normalize-pathname.ts。
【免费下载链接】scalarScalar is an open-source API platform: 🌐 Modern REST API Client 📖 Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考