Next.js 13实验性appDir部署后<head>中<meta>与<title>不渲染
解决Next.js 13 appDir + MUI 5 SSR下标签不渲染的问题
你的核心问题出在layout.tsx里重复渲染了两组<html>和<head>标签,这违反了Next.js App Router的规则——RootLayout必须返回单个<html>根元素,重复的结构会导致Next.js无法正确将head.tsx的内容注入到服务端渲染的<head>中。
修正步骤:
1. 重构app/layout.tsx,保留单一根元素
把重复的<html>/<head>移除,将MUI的ThemeProvider放到<body>内部,因为主题只需要作用于页面内容:
import { SSRThemeProvider } from "lib/SSR/theme"; import React from "react"; import theme from "styles/appTheme"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <head /> {/* Next.js会自动注入head.tsx的内容 */} <body> <SSRThemeProvider theme={theme}> <React.StrictMode> {children} </React.StrictMode> </SSRThemeProvider> </body> </html> ); }
2. 精简lib/SSR/theme.provider.tsx,移除重复的StrictMode
RootLayout已经添加了React.StrictMode,不需要在ThemeProvider里重复:
"use client"; import { ThemeProvider } from "@mui/material"; import { DefaultTheme, ThemeProviderProps } from "@mui/styles"; import React from "react"; export const SSRThemeProvider = <T = DefaultTheme>( props: ThemeProviderProps<T> ): React.ReactElement<ThemeProviderProps<T>> => { return <ThemeProvider {...props} />; };
3. 保持head.tsx原有写法即可
export default function Head() { return ( <> <title>My App</title> </> ); }
关键说明:
- Next.js App Router会自动将
head.tsx的内容合并到服务端渲染的<head>中,前提是RootLayout只有一个<html>根元素。 - MUI的
ThemeProvider不需要包裹整个<html>结构,仅作用于<body>内的页面内容即可满足SSR需求。
重新构建部署到Vercel后,查看服务端渲染的源码,就能看到<head>中正确渲染的<title>标签了。
内容的提问来源于stack exchange,提问作者brandonscript
相关产品推荐
相关产品推荐

