如何在Next.js App Router中实现路由嵌套,避免内容重复
问题原因
根布局app/layout.js是所有路由的共享父布局,所有页面都会嵌套在它的children中。如果直接在根布局里添加根页面的内容,访问/时,根布局的内容会和根页面page.js的内容重复渲染;访问/student时虽然能得到想要的效果,但根页面的重复问题无法解决。
解决方案
方案1:给student路由添加专属布局(推荐)
在student目录下新建layout.js,在这个布局里同时渲染根页面组件和student页面内容:
// app/student/layout.js import RootPage from '../page'; export default function StudentLayout({ children }) { return ( <> <RootPage /> {children} </> ); }
这样访问/student时会先显示根页面内容,再显示student页面内容;访问/时正常显示根页面,无重复问题。
方案2:直接在student页面导入根页面组件
修改student/page.js,直接引入根页面组件并渲染:
// app/student/page.js import RootPage from '../page'; export default function Page() { return ( <> <RootPage /> <h1>Hello, Student</h1> </> ); }
这个方案更直接,不需要额外布局文件,效果和方案1一致。
方案3:通过路由判断在根布局处理(不推荐)
如果一定要在根布局实现,可使用usePathname钩子判断当前路由,仅在/student时额外渲染根页面内容:
// app/layout.js import { Inter } from "next/font/google"; import { usePathname } from 'next/navigation'; import RootPage from './page'; const inter = Inter({ subsets: ["latin"] }); export const metadata = { title: "Create Next App", description: "Generated by create next app", }; export default function RootLayout({ children }) { const pathname = usePathname(); return ( <html lang="en"> <body className={inter.className}> {pathname === '/student' && <RootPage />} {children} </body> </html> ); }
不推荐此方案的原因是:根布局作为全局共享布局,应避免和具体路由绑定逻辑,不利于后续维护。
内容的提问来源于stack exchange,提问作者Sriram Prasanth
相关产品推荐
相关产品推荐

