logoNamu Design

⌘ K
  • Design
  • Development
  • Components
  • Blog
  • Resources
1.0.0
  • Namu Design of React
  • Changelogv1.0.0
  • Basic Usage
    • Getting Started
    • Usage with create-react-app
    • Usage with Next.js
    • Usage with Umi
    • Usage with Vite
  • Advanced
    • Customize ThemeUpdated
    • CSS Compatible
    • Server Side RenderingNew
    • Use custom date library
    • Internationalization
  • Migration
    • V4 to V5
    • Less variables to Component Token
  • Other
    • Common Props
    • Third-Party Libraries
    • Contributing
    • FAQ
Inline Style
Whole Export
Custom theme
Mixed theme
Extract on demand

Server Side Rendering

  • CSS CompatibleUse custom date library

    Resources

    Namu Design Charts
    Namu Design Pro
    Namu Design Pro Components
    Namu Design Mobile
    Namu Design Mini
    Namu Design Landing-Landing Templates
    Scaffolds-Scaffold Market
    Umi-React Application Framework
    dumi-Component doc generator
    qiankun-Micro-Frontends Framework
    ahooks-React Hooks Library
    Ant Motion-Motion Solution
    China Mirror 🇨🇳

    Community

    Awesome Namu Design
    Medium
    Twitter
    yuqueNamu Design in YuQue
    Namu Design in Zhihu
    Experience Cloud Blog
    seeconfSEE Conf-Experience Tech Conference

    Help

    GitHub
    Change Log
    FAQ
    Bug Report
    Issues
    Discussions
    StackOverflow
    SegmentFault

    Ant XTechMore Products

    yuqueYuQue-Document Collaboration Platform
    AntVAntV-Data Visualization
    EggEgg-Enterprise Node.js Framework
    kitchenKitchen-Sketch Toolkit
    xtechAnt Financial Experience Tech
    Theme Editor
    Made with ❤ by
    Ant Group and Namu Design Community

    There are two options for server-side rendering styles, each with advantages and disadvantages:

    • Inline mode: there is no need to request additional style files during rendering. The advantage is to reduce additional network requests. The disadvantage is that the HTML volume will increase and the speed of the first screen rendering will be affected. Relevant discussion: #39891
    • Whole export: The antd component is pre-baked and styled as a css file to be introduced in the page. The advantage is that when opening any page, the same set of css files will be reused just like the traditional css scheme to hit the cache. The disadvantage is that if there are multiple themes in the page, additional baking is required

    Inline Style

    Use @ant-design/cssinjs to extract style:

    import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
    import { renderToString } from 'react-dom/server';
    export default () => {
    // SSR Render
    const cache = createCache();
    const html = renderToString(
    <StyleProvider cache={cache}>
    <MyApp />
    </StyleProvider>,
    );
    // Grab style from cache
    const styleText = extractStyle(cache);
    // Mix with style
    return `
    <!DOCTYPE html>
    <html>
    <head>
    ${styleText}
    </head>
    <body>
    <div id="root">${html}</div>
    </body>
    </html>
    `;
    };

    Whole Export

    If you want to detach a style file into a css file, try the following schemes:

    1. Installation dependency
    npm install ts-node tslib cross-env --save-dev
    1. Add tsconfig.node.json
    {
    "compilerOptions": {
    "strictNullChecks": true,
    "module": "NodeNext",
    "jsx": "react",
    "esModuleInterop": true
    },
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
    }
    1. Add scripts/genAntdCss.tsx
    // scripts/genAntdCss.tsx
    import fs from 'fs';
    import { extractStyle } from '@ant-design/static-style-extract';
    const outputPath = './public/antd.min.css';
    const css = extractStyle();
    fs.writeFileSync(outputPath, css);

    If you want to use mixed themes or custom themes, you can use the following script:

    import fs from 'fs';
    import { extractStyle } from '@ant-design/static-style-extract';
    import React from 'react';
    import { ConfigProvider } from 'antd';
    const outputPath = './public/antd.min.css';
    const testGreenColor = '#008000';
    const testRedColor = '#ff0000';
    const css = extractStyle((node) => (
    <>
    <ConfigProvider
    theme={{
    token: {
    colorBgBase: testGreenColor,
    },
    }}
    >
    {node}
    </ConfigProvider>
    <ConfigProvider
    theme={{
    token: {
    colorPrimary: testGreenColor,
    },
    }}
    >
    <ConfigProvider
    theme={{
    token: {
    colorBgBase: testRedColor,
    },
    }}
    >
    {node}
    </ConfigProvider>
    </ConfigProvider>
    </>
    ));
    fs.writeFileSync(outputPath, css);

    You can choose to execute this script before starting the development command or before compiling. Running this script will generate a full antd.min.css file directly in the specified directory of the current project (e.g. public).

    Take Next.js for example(example):

    // package.json
    {
    "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "predev": "ts-node --project ./tsconfig.node.json ./scripts/genAntdCss.tsx",
    "prebuild": "cross-env NODE_ENV=production ts-node --project ./tsconfig.node.json ./scripts/genAntdCss.tsx"
    }
    }

    Then, you just need to import this file into the pages/_app.tsx file:

    import { StyleProvider } from '@ant-design/cssinjs';
    import type { AppProps } from 'next/app';
    import '../public/antd.min.css'; // add this line
    import '../styles/globals.css';
    export default function App({ Component, pageProps }: AppProps) {
    return (
    <StyleProvider hashPriority="high">
    <Component {...pageProps} />
    </StyleProvider>
    );
    }

    Custom theme

    If you're using a custom theme for your project, try baking in the following ways:

    import { extractStyle } from '@ant-design/static-style-extract';
    import { ConfigProvider } from 'antd';
    const cssText = extractStyle((node) => (
    <ConfigProvider
    theme={{
    token: {
    colorPrimary: 'red',
    },
    }}
    >
    {node}
    </ConfigProvider>
    ));

    Mixed theme

    If you're using a mixed theme for your project, try baking in the following ways:

    import { extractStyle } from '@ant-design/static-style-extract';
    import { ConfigProvider } from 'antd';
    const cssText = extractStyle((node) => (
    <>
    <ConfigProvider
    theme={{
    token: {
    colorBgBase: 'green ',
    },
    }}
    >
    {node}
    </ConfigProvider>
    <ConfigProvider
    theme={{
    token: {
    colorPrimary: 'blue',
    },
    }}
    >
    <ConfigProvider
    theme={{
    token: {
    colorBgBase: 'red ',
    },
    }}
    >
    {node}
    </ConfigProvider>
    </ConfigProvider>
    </>
    ));

    More about static-style-extract, see static-style-extract.

    Extract on demand

    // scripts/genAntdCss.tsx
    import { createHash } from 'crypto';
    import fs from 'fs';
    import path from 'path';
    import type Entity from '@ant-design/cssinjs/lib/Cache';
    import { extractStyle } from '@ant-design/cssinjs';
    export type DoExtraStyleOptions = {
    cache: Entity;
    dir?: string;
    baseFileName?: string;
    };
    export function doExtraStyle({
    cache,
    dir = 'antd-output',
    baseFileName = 'antd.min',
    }: DoExtraStyleOptions) {
    const baseDir = path.resolve(__dirname, '../../static/css');
    const outputCssPath = path.join(baseDir, dir);
    if (!fs.existsSync(outputCssPath)) {
    fs.mkdirSync(outputCssPath, { recursive: true });
    }
    const css = extractStyle(cache, true);
    if (!css) return '';
    const md5 = createHash('md5');
    const hash = md5.update(css).digest('hex');
    const fileName = `${baseFileName}.${hash.substring(0, 8)}.css`;
    const fullpath = path.join(outputCssPath, fileName);
    const res = `_next/static/css/${dir}/${fileName}`;
    if (fs.existsSync(fullpath)) return res;
    fs.writeFileSync(fullpath, css);
    return res;
    }

    Export on demand using the above tools in _document.tsx

    // _document.tsx
    import { StyleProvider, createCache } from '@ant-design/cssinjs';
    import type { DocumentContext } from 'next/document';
    import Document, { Head, Html, Main, NextScript } from 'next/document';
    import { doExtraStyle } from '../scripts/genAntdCss';
    export default class MyDocument extends Document {
    static async getInitialProps(ctx: DocumentContext) {
    const cache = createCache();
    let fileName = '';
    const originalRenderPage = ctx.renderPage;
    ctx.renderPage = () =>
    originalRenderPage({
    enhanceApp: (App) => (props) => (
    <StyleProvider cache={cache}>
    <App {...props} />
    </StyleProvider>
    ),
    });
    const initialProps = await Document.getInitialProps(ctx);
    // 1.1 extract style which had been used
    fileName = doExtraStyle({
    cache,
    });
    return {
    ...initialProps,
    styles: (
    <>
    {initialProps.styles}
    {/* 1.2 inject css */}
    {fileName && <link rel="stylesheet" href={`/${fileName}`} />}
    </>
    ),
    };
    }
    render() {
    return (
    <Html lang="en">
    <Head />
    <body>
    <Main />
    <NextScript />
    </body>
    </Html>
    );
    }
    }

    See the demo:Export the css files on demand demo