Skip to content

覆盖默认值

自定义 Markdown 版本、llms.txt 索引和 OG 卡片,无需放弃共享路由。

AI 生成 · 待审阅更新于 查看 Markdown

脚手架的 src/pages/[...slug]/index.md.ts 和 src/pages/[...slug]/index.mdx.ts 路由为每个页面提供 Markdown 和源版本。你可以在三个层级上更改它们的输出:

  • 包装共享路由以更改所有页面的输出。
  • 用自己的代码替换共享路由。
  • 添加更具体的路由文件来接管单个集合。

示例使用 .md 路由。.mdx 路由使用 markdownSourceRoute() 的方式相同。llms.txt 路由和 OG 卡片路由遵循相同的模式;请参阅覆盖 llms.txt 索引和自定义 OG 卡片。

包装共享路由

调用共享路由的 GET,然后更改其响应。此示例向每个 Markdown 版本添加许可证行:

src/pages/[...slug]/index.md.tsts
import type { APIRoute } from "astro";
import { markdownRoute } from "@cloudflare/nimbus-docs/agent-endpoints";

export const prerender = true;

const route = markdownRoute();
export const getStaticPaths = route.getStaticPaths;

export const GET: APIRoute = async (context) => {
  const response = await route.GET(context);
  if (!response.ok) return response;
  const body = await response.text();
  return new Response(`${body}\nLicensed under CC BY 4.0.\n`, {
    headers: response.headers,
  });
};

替换共享路由

使用 @cloudflare/nimbus-docs/agent-endpoints 中的公共辅助函数编写自己的 GET。getMarkdownPayload() 以 body 形式返回页面生成的 Markdown,以 content 形式返回仅页面内容(不含 frontmatter 和索引前言)。保留共享路由的 getStaticPaths:它列出每个集合的页面,跳过更具体路由拥有的页面,并将每个页面的 reference 作为 prop 传递。

此示例仅提供页面内容:

src/pages/[...slug]/index.md.tsts
import type { APIRoute } from "astro";
import {
  getMarkdownPayload,
  markdownRoute,
  type MarkdownEndpointReference,
} from "@cloudflare/nimbus-docs/agent-endpoints";

export const prerender = true;

export const { getStaticPaths } = markdownRoute();

export const GET: APIRoute = async ({ props, request }) => {
  const { reference } = props as { reference: MarkdownEndpointReference };
  const payload = await getMarkdownPayload({
    collection: reference.collection,
    surface: "markdown",
    reference,
    context: { request },
  });
  if (!payload) return new Response("Not found", { status: 404 });
  return new Response(payload.content, {
    headers: { "Content-Type": payload.mediaType },
  });
};

要自己列出页面,getMarkdownStaticPaths({ collection, surface }) 返回一个集合的路径。基于它构建的路由仅服务它列出的集合。

接管单个集合

Astro 对更具体的路由赋予更高优先级。在集合的 URL 前缀下添加路由文件,它将服务该集合的 Markdown 版本。共享路由会跳过更具体路由模式匹配的所有 URL。

markdownRoute() 可在任何路由文件中使用,仅服务其路由匹配的 URL。包装它以自定义单个集合:

src/pages/blog/[...slug]/index.md.tsts
import type { APIRoute } from "astro";
import { markdownRoute } from "@cloudflare/nimbus-docs/agent-endpoints";

export const prerender = true;

const route = markdownRoute();
export const getStaticPaths = route.getStaticPaths;

export const GET: APIRoute = async (context) => {
  const response = await route.GET(context);
  if (!response.ok) return response;
  const body = await response.text();
  return new Response(`${body}\nSubscribe at https://example.com/blog/rss.xml\n`, {
    headers: response.headers,
  });
};

或者使用公共辅助函数编写路由。更新日志配方(nimbus-docs add changelog)添加了 src/pages/changelog/[...slug]/index.md.ts,它使用每个条目的日期和标签构建自己的 frontmatter:

src/pages/changelog/[...slug]/index.md.ts (abridged)ts
export const prerender = true;

export const getStaticPaths = async () =>
  getMarkdownStaticPaths({ collection: "changelog", surface: "markdown" });

export async function GET({ params, props, request }: SlugContext) {
  const payload = await getMarkdownPayload({
    collection: "changelog",
    surface: "markdown",
    slug: params.slug,
    reference: props.reference,
    context: { request },
  });
  if (!payload) return new Response("Not found", { status: 404 });
  // 从条目的数据构建 frontmatter,然后追加 payload.content。
}

更具体的路由必须生成其模式匹配的每个页面。如果跳过某些页面,这些页面将没有 Markdown 版本,而 llms.txt 仍然会链接到它们。Nimbus 会在构建警告中列出缺失的路径和拥有的路由。当 Astro 的 prerenderConflictBehavior 设置为 "error" 时,构建会直接失败。

覆盖 llms.txt 索引

脚手架的 llms.txt 路由调用 llmsRoute()、llmsFullRoute() 和 llmsSectionRoute()。以相同方式包装返回的 GET。此示例向 /llms.txt 添加支持链接:

src/pages/llms.txt.tsts
import type { APIRoute } from "astro";
import { llmsRoute } from "@cloudflare/nimbus-docs/agent-endpoints";

export const prerender = true;

const route = llmsRoute();

export const GET: APIRoute = async (context) => {
  const response = await route.GET(context);
  if (!response.ok) return response;
  const body = await response.text();
  return new Response(`${body}\n## Support\n\n- [Contact support](https://example.com/support)\n`, {
    headers: response.headers,
  });
};

对于分节索引,保留 llmsSectionRoute() 的 getStaticPaths(它列出每个分节),并包装其 GET。要从头构建正文,请使用 reference(如 { scope: "section", surface: "index", section: "writing" })调用 getLlmsPayload();对于未知索引,它返回 null。

自定义 OG 卡片

脚手架的 src/pages/og/[...slug].ts 将 getOgImagePages() 传递给 astro-og-canvas。该映射每个页面一个条目,键使得每张卡片写入该页面的 ogImageUrl,每个值是页面的 IndexedEntry。在 src/pages/og/_og-card-config.ts 中更改卡片外观,或在 getImageOptions 中逐页更改。此示例为更新日志卡片添加标签:

src/pages/og/[...slug].tsts
import { getOgImagePages } from "@cloudflare/nimbus-docs/runtime";
import { OGImageRoute } from "astro-og-canvas";
import { ogCardConfig } from "./_og-card-config";

export const prerender = true;

export const { getStaticPaths, GET } = await OGImageRoute({
  pages: await getOgImagePages(),
  getImageOptions: (_path, page) => ({
    title: page.collection === "changelog" ? `Changelog: ${page.title}` : page.title,
    description: page.description ?? "",
    ...ogCardConfig,
  }),
});

请将路由保持在 src/pages/og/[...slug].ts,保持映射的键、默认的 getSlug 和 PNG 输出:页面路由链接到 ogImageUrl,因此更改位置、键、slug 或格式会导致页面指向不存在的卡片。frontmatter 中设置了 socialImage 的页面会使用该图片,因为页面路由传递的是 entry.data.socialImage ?? ogImageUrl。

覆盖更改了什么

覆盖仅更改该路由提供的内容。llms-full.txt 和托管 MCP 仍使用 Nimbus 生成的 Markdown。

共享路由和使用 markdownRoute() 或 markdownSourceRoute() 的路由必须保持 export const prerender = true。如果在请求时渲染,构建会失败。

在路由文件本身中调用工厂函数,如上面的示例所示。与 Astro 自己的 prerender 检测一样,Nimbus 通过读取路由文件来查找它,因此从另一个模块重新导出的工厂函数在构建启动时不会被检查。在构建结束时,Nimbus 会警告每个没有预渲染路由生成的 Markdown 版本和 llms.txt 索引,并指出服务它的路由。

导航

输入以搜索…

↑↓ 导航↵ 选择Esc 关闭