> For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt.

# 服务端与框架

解析与准备都不依赖 React，可以在服务端、构建期或 Worker 中完成。客户端只加载 `react-wikitext/view`，接收并恢复渲染快照。

## 两种部署方式

| 方式          | 服务端做什么      | 客户端加载            | 适合             |
| ----------- | ----------- | ---------------- | -------------- |
| 客户端渲染源码     | 只发送源文本      | 根入口（解析器 + React） | 内容量小、按需交互      |
| 服务端准备，客户端渲染 | 解析、准备、序列化快照 | `/view` + 恢复函数   | 内容稳定、希望减小客户端体积 |

第二种方式把解析成本留在服务端；客户端不再加载 `wikiparser-node`。

## 服务端准备

```tsx
// server.tsx
import { createWikiparser } from "react-wikitext/parse";
import { prepareWikitext, serializeWikitextRenderDocument } from "react-wikitext/hast";

const parser = createWikiparser();

export function preparePayload(source: string, pageName: string) {
  const document = parser.parse(source, { pageName });
  const prepared = prepareWikitext(document);
  return serializeWikitextRenderDocument(prepared);
}
```

```tsx
// client.tsx
"use client";

import { useMemo } from "react";
import { restoreWikitextRenderDocument } from "react-wikitext/hast";
import { WikitextView } from "react-wikitext/view";

export function Article({ payload }: { payload: unknown }) {
  const prepared = useMemo(() => restoreWikitextRenderDocument(payload), [payload]);
  return <WikitextView document={prepared} lang="zh-CN" />;
}
```

`restoreWikitextRenderDocument` 会重新校验结构版本、根节点、HAST 结构与节点预算，并重新执行最终清洗。它不信任任意第三方 HAST；只恢复来自可信服务端或可信缓存的快照。

:::note
快照同时包含语义树、HAST 与源码，体积明显大于纯 HTML。大文档应按页或按块准备，并评估传输预算。
:::

## Next.js App Router

根入口与 `/view` 在模块加载时创建 Context，并使用 React Hook，因此只能在客户端组件中运行。这两个入口的产物顶部带有 `"use client"` 指令，宿主不需要额外建立边界；服务端只使用 `/parse`、`/hast`。

```tsx
// app/wiki/[title]/page.tsx
import { createWikiparser } from "react-wikitext/parse";
import { prepareWikitext, serializeWikitextRenderDocument } from "react-wikitext/hast";
import { ArticleView } from "./article-view";
import { loadPageSource } from "@/lib/wiki";

const parser = createWikiparser();

export default async function Page({ params }: { params: Promise<{ title: string }> }) {
  const { title } = await params;
  const source = await loadPageSource(title);
  const document = parser.parse(source, { pageName: title });
  const payload = serializeWikitextRenderDocument(prepareWikitext(document));

  return <ArticleView payload={payload} lang="zh-CN" />;
}
```

```tsx
// app/wiki/[title]/article-view.tsx
"use client";

import { useMemo } from "react";
import { restoreWikitextRenderDocument } from "react-wikitext/hast";
import { WikitextView } from "react-wikitext/view";

export function ArticleView({ payload, lang }: { payload: unknown; lang: string }) {
  const prepared = useMemo(() => restoreWikitextRenderDocument(payload), [payload]);
  return <WikitextView document={prepared} lang={lang} />;
}
```

```tsx
// app/layout.tsx
import "react-wikitext/styles.css";
```

- 服务端准备阶段只调用 `/parse` 与 `/hast`；这两个入口不加载 React。
- 客户端组件只负责恢复与渲染，不重新解析。
- 根入口与 `/view` 带 `"use client"`，Next.js 会把它们视为客户端边界：可以在 Server Component 中直接渲染，但解析随之发生在客户端。需要服务端解析时，按上面的页面组件先准备快照。
- 在其他 SSR 环境中，可以用 `renderToStaticMarkup` 渲染 `WikitextView`，再让客户端用同一份快照 hydrate。

## Vite 与其他 SSR

普通 SSR 的思路相同：服务端准备快照，把它作为页面数据发送给客户端，客户端用 `/view` 恢复并挂载。

```ts
// server entry
const payload = serializeWikitextRenderDocument(prepareWikitext(document));
const html = template.replace("__WIKITEXT__", JSON.stringify(payload).replace(/</gu, "\\u003c"));
```

- 内联 JSON 时转义 `<`，避免 `</script>` 提前结束脚本。
- 如果页面要由搜索引擎直接读取正文，可以在服务端渲染 `WikitextView`；此时客户端必须用同一份快照、同一棵树 hydrate。

## Hydration 与锚点

- `headingIdStrategy: "instance"` 使用 `useId` 生成实例前缀，服务端与客户端渲染同一棵树时保持一致。
- 如果服务端与客户端结构不同，或同一页有多个实例，显式传入 `idPrefix` 固定前缀。
- 需要与宿主约定裸锚点（例如已有 `#Section` 链接）时，使用 `headingIdStrategy: "mediawiki"`；它假设页面只有一个实例。
- `headingIdStrategy: "none"` 不写 id，也不生成目录链接，适合不需要锚点的嵌入式展示。

## 缓存

渲染快照可以缓存，但键必须覆盖所有影响输出的输入：

- `AST_SCHEMA_VERSION`、`RENDER_SCHEMA_VERSION` 与解析器版本。
- 源码与 `pageName`。
- 站点配置（`config`）。
- `prepareOptions`：解析函数、插件、`policy`、`labels`、`headingIdStrategy` 与 `handlers`。

恢复函数会拒绝版本不匹配的快照；升级库或解析器时应让缓存整体失效。解析结果的缓存策略见[性能与预算](/zh/guide/performance.md)。

## 相关

- [基本用法](/zh/guide/usage.md)：源码组件与显式管线。
- [准备 `/hast`](/zh/api/prepare.md)：序列化、恢复与预算。
- [安全模型](/zh/guide/security.md)：快照信任边界。
