在 Next.js 中引入 Ant Design (antd) 的关键在于解决服务端渲染 (SSR) 的样式问题 。根据你使用的是最新的 App Router 还是传统的 Pages Router,配置方式完全不同。
📦 package.json 依赖配置
首先,安装核心依赖。根据你的路由模式二选一:
json
{
"dependencies": {
"antd": "^5.0.0", // 核心组件库,两者都需要
"next": "14.x",
// --- App Router (推荐) ---
"@ant-design/nextjs-registry": "^1.0.0", // 处理App Router下的SSR样式
// --- Pages Router (旧项目) ---
// "@ant-design/cssinjs": "^1.0.0" // 处理Pages Router下的样式抽取
}
}
🛠️ 配置与使用代码
1. App Router (Next.js 13/14/15 推荐)
这是目前新项目的标准做法,使用 @ant-design/nextjs-registry 包裹根布局。
步骤 1:修改根布局 (app/layout.tsx)
这是最关键的一步,用于注册 Antd 样式。
tsx
import { AntdRegistry } from '@ant-design/nextjs-registry';
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'My App',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{/* 使用 AntdRegistry 包裹子节点 */}
<AntdRegistry>{children}</AntdRegistry>
</body>
</html>
);
}
步骤 2:在页面中使用组件 (app/page.tsx)
tsx
'use client'; // 如果使用了交互式组件(如Modal),需标记为客户端组件
import { Button, DatePicker, Space } from 'antd';
export default function HomePage() {
return (
<div style={{ padding: 50 }}>
<Space direction="vertical">
<Button type="primary">Antd Button</Button>
<DatePicker />
</Space>
</div>
);
}
2. Pages Router (旧版 Next.js)
如果你的项目还在使用 pages 目录,需要通过 _app.tsx 和 _document.tsx 配置。
步骤 1:修改 pages/_document.tsx
用于抽取 SSR 阶段的样式并注入到 HTML 头部。
tsx
import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document';
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const cache = createCache();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => (
<StyleProvider cache={cache}>
<App {...props} />
</StyleProvider>
),
});
const initialProps = await Document.getInitialProps(ctx);
const style = extractStyle(cache, true);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
<style dangerouslySetInnerHTML={{ __html: style }} />
</>
),
};
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
步骤 2:修改 pages/_app.tsx
tsx
import type { AppProps } from 'next/app';
import { ConfigProvider } from 'antd';
export default function App({ Component, pageProps }: AppProps) {
return (
<ConfigProvider
theme={{
token: {
colorPrimary: '#00b96b', // 可选:自定义主题
},
}}
>
<Component {...pageProps} />
</ConfigProvider>
);
}
⚙️ Next.js 构建配置 (next.config.js)
Antd 使用了一些 ES6+ 语法,为了确保兼容性,需要在 next.config.js 中配置转译:
javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: [
'antd',
'@ant-design',
'rc-util',
'rc-pagination',
'rc-picker',
'rc-notification',
'rc-tooltip',
'rc-tree',
'rc-table',
],
};
module.exports = nextConfig;
🎯 最佳实践与避坑指南
-
路由模式判断 :检查你的项目根目录是
app还是pages。新项目请务必使用 App Router。 -
子组件引入方式 (App Router) :在 App Router 下,避免使用
Select.Option这种点语法,改为直接引入:tsx// ❌ 避免 import { Select } from 'antd'; const { Option } = Select; // ✅ 推荐 import Select, { Option } from 'antd/es/select'; -
版本一致性 :如果使用 Pages Router,确保
@ant-design/cssinjs的版本与antd内部依赖的版本一致,否则可能导致 React 实例冲突。