Skip to content

Commit 857d9c1

Browse files
committed
fix(build): Server Component 里不能用 next/dynamic({ssr:false})
Vercel preview 挂在这句: const DocShareButton = dynamic(..., { ssr: false }); Next.js 15+ 明确禁止 Server Component 里使用 next/dynamic 的 ssr:false 选项 (本地 turbopack dev 宽容不报,production build 必 fail)。 之前引入它是为了避开疑似 fumadocs PageTOCPopover 的 hydration mismatch, 但 DocShareButton 本身已是 'use client' 组件,useState 不会影响 sibling 的 useId 计数;实际 local + vercel build 都不再复现该 mismatch,直接走标准 'use client' 导入即可。 pnpm build 本地通过。
1 parent 91f0079 commit 857d9c1

1 file changed

Lines changed: 1 addition & 14 deletions

File tree

app/docs/[...slug]/page.tsx

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,7 @@ import { Contributors } from "@/app/components/Contributors";
1414
import { DocsAssistant } from "@/app/components/DocsAssistant";
1515
import { LicenseNotice } from "@/app/components/LicenseNotice";
1616
import { PageFeedback } from "@/app/components/PageFeedback";
17-
import dynamic from "next/dynamic";
18-
19-
// 仅在客户端渲染 DocShareButton:
20-
// 该按钮挂在 fumadocs DocsPage 内部,fumadocs 的 PageTOCPopover 会调 useId 生成
21-
// Radix Collapsible 的 aria-controls;如果 DocShareButton 参与 SSR,会让 server 端
22-
// 的 useId 计数与 client 端不一致,触发 hydration mismatch。
23-
// 改为 ssr: false 后此按钮完全在客户端 mount,不再污染 fumadocs 的 useId 顺序。
24-
const DocShareButton = dynamic(
25-
() =>
26-
import("@/app/components/DocShareButton").then((m) => ({
27-
default: m.DocShareButton,
28-
})),
29-
{ ssr: false },
30-
);
17+
import { DocShareButton } from "@/app/components/DocShareButton";
3118
// Extract clean text content from MDX - no longer used on client/page side
3219
// content fetching moved to API route for performance
3320

0 commit comments

Comments
 (0)