Next.js报错:服务端HTML中<div>需匹配<body>,求添加body类名正确方法
Next.js中正确给添加类名的方法(避免重复标签报错)
你遇到的Expected server HTML to contain a matching <body> in <div>警告,本质是手动写的<body>标签和Next.js框架自动生成的<body>冲突,导致页面出现两个<body>节点,服务端渲染的HTML和客户端 hydration 时的结构不匹配。
下面分两种路由模式给出解决方案:
Pages Router(Next.js 12及更早版本)
需要在项目的pages目录下创建或修改_document.js(或_document.tsx)文件——这个文件是Next.js负责渲染根HTML结构的入口,在这里修改<body>不会产生重复标签:
// pages/_document.js import Document, { Html, Head, Main, NextScript } from 'next/document'; class MyDocument extends Document { render() { return ( <Html> <Head /> <body className="lines"> <Main /> <NextScript /> </body> </Html> ); } } export default MyDocument;
之后删除你页面代码中手动写的<body>标签,只保留内部的<Layout>、<NextProgress>等内容即可。
App Router(Next.js 13+)
在App Router模式下,根布局文件app/layout.js(或app/layout.tsx)负责渲染全局HTML结构,直接在这里给<body>添加类名:
// app/layout.js export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body className="lines"> {children} </body> </html> ); }
同样要移除页面中手动添加的<body>标签,确保只有根布局里的<body>存在。
动态修改类名(可选)
如果需要根据页面切换动态调整<body>的类名,可以结合客户端组件和路由状态实现:
以App Router为例:
'use client'; import { usePathname } from 'next/navigation'; import { useEffect } from 'react'; export default function RootLayout({ children }) { const pathname = usePathname(); useEffect(() => { // 根据当前路径切换类名 document.body.classList.toggle('about-page', pathname === '/about'); }, [pathname]); return ( <html lang="zh-CN"> <body className="lines"> {children} </body> </html> ); }
内容的提问来源于stack exchange,提问作者Inshad Bajwa
相关产品推荐
相关产品推荐

