如何在Next.js 14 App Router中无需"use client"使用MUI styled components
在Next.js 14 App Router中使用MUI Styled Components并保留SSR
你可以通过集中管理客户端标记和组件边界分离的方式,避免在每个页面添加"use client",同时保留Next.js的SSR特性,具体步骤如下:
1. 创建共享的Styled工具文件
首先创建一个单独的客户端文件,统一导入MUI的styled并导出,只在这个文件中添加"use client"指令:
// src/app/styled.ts 'use client'; import { styled as muiStyled } from '@mui/material/styles'; export const styled = muiStyled;
后续所有需要创建styled组件的场景,都从这个文件导入styled,而非直接从@mui/material/styles导入。
2. 定义客户端Styled组件
将所有styled组件的定义放在单独的客户端组件文件中,仅在这些文件中添加"use client"(如果是独立组件文件)。例如:
// src/components/StyledCard.tsx 'use client'; import { styled } from '../app/styled'; export const StyledCard = styled('div')(({ theme }) => ({ padding: theme.spacing(2), border: `1px solid ${theme.palette.divider}`, borderRadius: theme.shape.borderRadius, boxShadow: theme.shadows[1], }));
3. 在服务器组件中使用Styled组件
你的页面、布局等服务器组件可以直接导入并使用上述客户端styled组件,无需添加"use client",Next.js会自动处理组件渲染边界,保证SSR正常工作:
// src/app/page.tsx import { StyledCard } from '../components/StyledCard'; export default function Home() { // 该页面是服务器组件,支持SSR return ( <main> <StyledCard> <h1>SSR内容 + MUI Styled组件</h1> <p>这个页面无需添加"use client"即可使用MUI样式</p> </StyledCard> </main> ); }
4. 配置SSR兼容的Theme Provider
为了确保MUI主题样式在SSR过程中正确渲染,需要创建客户端版本的Theme Provider,并在根布局中引入:
// src/components/ThemeProvider.tsx 'use client'; import { ThemeProvider as MuiThemeProvider, createTheme } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; // 自定义你的MUI主题 const theme = createTheme({ palette: { mode: 'light', primary: { main: '#1976d2', }, }, }); export function ThemeProvider({ children }: { children: React.ReactNode }) { return ( <MuiThemeProvider theme={theme}> <CssBaseline /> {children} </MuiThemeProvider> ); }
然后在根布局中使用这个客户端Theme Provider:
// src/app/layout.tsx import type { Metadata } from 'next'; import { ThemeProvider } from './components/ThemeProvider'; export const metadata: Metadata = { title: 'MUI + Next.js 14 SSR', description: '在App Router中实现MUI样式与SSR共存', }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body> <ThemeProvider>{children}</ThemeProvider> </body> </html> ); }
关键注意事项
- 所有直接使用MUI
styledAPI的组件必须是客户端组件,但可以集中在少数文件中,避免每个页面重复添加"use client" - 服务器组件可以安全地渲染客户端styled组件,Next.js会自动处理客户端 hydration,不影响SSR流程
- 确保Theme Provider是客户端组件,否则无法在SSR中正确注入样式
内容的提问来源于stack exchange,提问作者Yatin
相关产品推荐
相关产品推荐

