Ant Design (AntD) — это популярная библиотека компонентов для React, которая предлагает готовые элементы интерфейса с продуманной стилистикой и функциональностью. При использовании серверного рендеринга (SSR, Server-Side Rendering) необходимо учитывать особенности работы стилей и компонентов AntD, чтобы корректно отображать интерфейс как на сервере, так и на клиенте.
Ant Design использует Less для генерации CSS, что требует особого подхода при SSR. Для корректного рендеринга необходимо импортировать стили таким образом, чтобы сервер мог их обработать.
Пример базовой конфигурации:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { ConfigProvider } from 'antd';
import App from './App';
import 'antd/dist/antd.css'; // Базовые стили
При использовании Next.js или аналогичных фреймворков рекомендуется
подключать стили глобально через _app.js или аналогичный
корневой файл. Это предотвращает проблемы с отсутствием CSS при
серверном рендеринге.
ConfigProvider для SSRКомпонент ConfigProvider позволяет задать глобальные
настройки AntD: локализацию, тему и поведение компонентов. При SSR важно
передавать одинаковую конфигурацию на сервере и клиенте.
import ruRU from 'antd/locale/ru_RU';
const app = (
<ConfigProvider locale={ruRU}>
<App />
</ConfigProvider>
);
Ключевые моменты:
locale — определяет язык компонентов (например,
календарей, сообщений, кнопок).prefixCls — позволяет изменять префикс CSS-классов, что
полезно при интеграции с CSS Modules или другими системами.Next.js предоставляет встроенную поддержку SSR, но AntD требует
особой обработки стилей. Для корректного рендеринга используется
библиотека @next/bundle-analyzer или кастомизация
_document.js.
Пример настройки _document.js:
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';
import { extractStyle } from 'antd/dist/antd.css';
class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
<style dangerouslySetInnerHTML={{ __html: extractStyle() }} />
</>
),
};
} finally {
sheet.seal();
}
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
Особенности:
ServerStyleSheet собирает стили при рендеринге на
сервере.extractStyle обеспечивает корректное подключение CSS
AntD.dangerouslySetInnerHTML используется только для
инлайн-стилей, полученных с сервера, чтобы избежать FOUC (flash of
unstyled content).Некоторые компоненты AntD (например, DatePicker,
Carousel) используют объекты window или
document. При SSR их рендерить на сервере нельзя.
Решения:
import dynamic from 'next/dynamic';
const DatePickerNoSSR = dynamic(() => import('antd').then(mod => mod.DatePicker), {
ssr: false,
});
window перед использованием:const isBrowser = typeof window !== 'undefined';
return isBrowser ? <DatePicker /> : null;
AntD позволяет кастомизировать тему через Less-переменные. Для SSR важно правильно передавать эти переменные на сервер, чтобы цвета и размеры совпадали с клиентской частью.
Пример с Next.js и
next-plugin-antd-less:
// next.config.js
const withAntdLess = require('next-plugin-antd-less');
module.exports = withAntdLess({
modifyVars: { '@primary-color': '#1DA57A' },
lessVarsFilePath: './src/styles/variables.less',
webpack(config) {
return config;
},
});
Преимущества:
При SSR важно минимизировать время генерации страниц:
babel-plugin-import для автоматического
tree-shaking:// babel.config.js
module.exports = {
plugins: [
[
'import',
{ libraryName: 'antd', libraryDirectory: 'es', style: 'css' },
],
],
};
React.memo для компонентов с частыми
ререндерингами.При SSR рекомендуется избегать конфликта стилей:
prefixCls в ConfigProvider
для изоляции классов AntD..module.css или
.module.less и применять локальные классы.Компоненты Modal, Tooltip,
Dropdown используют портал (React Portal) для рендеринга
поверх DOM. При SSR необходимо:
document.body)
существует.getContainer={typeof window !== 'undefined' ? () => document.body : undefined}.babel-plugin-import.window/document.Эти подходы обеспечивают корректный рендеринг интерфейса, предотвращают FOUC и повышают производительность при использовании Ant Design с SSR.