You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13中使用MUI与Styled Components的FOUC问题求助

在Next.js 13中解决Styled Components + MUI的FOUC问题

Next.js 13分为Pages Router和App Router两种路由模式,针对不同模式,Styled Components的FOUC问题有不同的适配方案,结合你使用MUI+Styled Components的场景,具体解决方案如下:


一、Pages Router 适配方案

你找到的Next.js 12的_document代码可以修改后适配Next.js 13的Pages Router,同时兼容Styled Components v6和MUI:

1. 安装编译优化依赖

先安装babel-plugin-styled-components,确保服务端渲染时样式正确注入:

npm install --save-dev babel-plugin-styled-components

2. 更新自定义_document.tsx/jsx

修改服务端样式收集逻辑,同时兼容MUI的服务端样式:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';
import { ServerStyleSheets as MuiServerStyleSheets } from '@mui/material/styles';

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const styledSheet = new ServerStyleSheet();
    const muiSheets = new MuiServerStyleSheets();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            styledSheet.collectStyles(muiSheets.collect(<App {...props} />)),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: [
          initialProps.styles,
          muiSheets.getStyleElement(),
          styledSheet.getStyleElement(),
        ],
      };
    } finally {
      styledSheet.seal();
    }
  }

  render() {
    return (
      <Html lang="en">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

3. 配置Babel(可选但推荐)

在项目根目录创建.babelrc文件,优化Styled Components编译:

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "styled-components",
      {
        "ssr": true,
        "displayName": true,
        "preprocess": false
      }
    ]
  ]
}

4. 确认MUI引擎配置

由于你已安装@mui/styled-engine-sc,MUI会自动使用Styled Components作为样式引擎。若样式优先级有问题,可在_app.tsx/jsx中添加配置:

import { ThemeProvider, createTheme } from '@mui/material/styles';
import { StyledEngineProvider } from '@mui/material/styles';

const theme = createTheme();

export default function App({ Component, pageProps }) {
  return (
    <StyledEngineProvider injectFirst>
      <ThemeProvider theme={theme}>
        <Component {...pageProps} />
      </ThemeProvider>
    </StyledEngineProvider>
  );
}

injectFirst可确保MUI样式不会被Styled Components覆盖,可根据需求调整。


二、App Router 适配方案

若你使用的是Next.js 13的App Router(app/目录),需要借助官方适配器处理服务端样式注入:

1. 安装适配器依赖

npm install @styled-components/nextjs-adapter

2. 修改next.config.js

启用Next.js对Styled Components的编译支持:

/** @type {import('next').NextConfig} */
const nextConfig = {
  compiler: {
    styledComponents: true,
  },
};

module.exports = nextConfig;

3. 配置Root Layout(app/layout.tsx)

在根布局中添加Styled Components和MUI的Provider,注意标记为客户端组件:

'use client';

import { StyledComponentsProvider } from '@styled-components/nextjs-adapter';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { StyledEngineProvider } from '@mui/material/styles';
import { ReactNode } from 'react';

const theme = createTheme();

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        <StyledEngineProvider injectFirst>
          <ThemeProvider theme={theme}>
            <StyledComponentsProvider>
              {children}
            </StyledComponentsProvider>
          </ThemeProvider>
        </StyledEngineProvider>
      </body>
    </html>
  );
}

4. 客户端组件标记

所有使用Styled Components的组件必须添加'use client'指令,因为Styled Components属于客户端库,无法在Server Components中使用:

'use client';

import styled from 'styled-components';

const StyledButton = styled.button`
  background: #2196f3;
  color: white;
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
`;

export default function MyButton() {
  return <StyledButton>点击按钮</StyledButton>;
}

通用最佳实践

  • App Router模式下,确保所有Styled Components代码都在标记了'use client'的组件中
  • 避免在服务端渲染组件中动态生成样式,尽量静态定义
  • 构建后清理浏览器缓存,确保最新样式文件加载
  • 检查是否存在重复的样式注入逻辑,避免冲突

内容的提问来源于stack exchange,提问作者Yonatan Galili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:09:53