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

NextJS子布局被父布局覆盖,访问/admin/login时HTML匹配报错求助

Next.js 服务端HTML匹配错误问题解决

项目结构

├── app
│   ├── admin
│   │   ├── login
│   │   │   ├── layout.js
│   │   │   └── page.js
│   │   ├── users
│   │   │   └── page.js
│   │   ├── layout.js
│   │   └── page.js
│   ├── layout.js
│   └── page.js

问题现象

访问localhost:3000/admin/login时,出现错误提示:"Expected server HTML to contain a matching in "。移除login目录下的layout.js后,错误消失;修改admin目录下的layout.js时,/admin/login页面也会同步显示修改内容。

相关代码

/admin/login/page.js

export default function Page() {
    return (
        <h1>Hello Login</h1>
    );
}

/admin/login/layout.js

import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"] });

export const metadata = {
    title: "Create Next App",
    description: "Generated by create next app",
};

export default function LoginLayout({ children }) {
    return (
        <html lang="en">
            <body className={inter.className}>{children}</body>
        </html>
    );
}

注:admin目录下的layout.js和page.js代码与上述login目录的代码一致

问题原因

在Next.js的App Router路由体系中,layout是嵌套继承的:app/layout.js → admin/layout.js → login/layout.js。你在login/layout.js和admin/layout.js中都返回了<html>和<body>标签,这会导致服务端渲染时生成重复的根标签结构,客户端水合过程中无法匹配服务端输出的HTML,从而触发错误。

解决方案

只保留最顶层的app/layout.js返回<html>和<body>,下层的admin/layout.js和login/layout.js仅返回包裹内容的容器即可,不需要重复根标签。

修改后的/admin/login/layout.js示例:

import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"] });

export const metadata = {
    title: "Create Next App",
    description: "Generated by create next app",
};

export default function LoginLayout({ children }) {
    return (
        <div className={inter.className}>{children}</div>
    );
}

同样,admin/layout.js也需要做类似修改,移除<html>和<body>标签,改用普通容器包裹children。


内容的提问来源于stack exchange,提问作者Carl Ortiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:50:08