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

使用Next.js Layout时页面内容显示在Mantine侧边栏下方的问题

侧边栏与页面内容布局问题(Mantine + Next.js)

我使用mantine.dev为应用创建侧边栏组件,通过Next.js Layout确保它在所有页面显示。链接功能正常,但页面实际内容显示在侧边栏下方而非侧边,效果如图:
应用测试页面截图

export function NavbarSimple() {
  const { classes, cx } = useStyles();
  const [active, setActive] = useState('Dashboard');

  const items = data.map((item, index) => (   
    <Link href={item.link} passHref style={{textDecoration: 'none'}}>
      <NavLink
        style={{ textDecoration: 'none' }}
        key={item.label}     
        // @ts-ignore
        active={index === active} 
        label={item.label}
        icon={<item.icon size={16} stroke={1.5} />}
        // @ts-ignore
        onClick={() => setActive(index)}

      />   
    </Link>
  ));

  return (
    <Navbar height='100vh' width={{ sm: '28vh' }} p="md" zIndex={0}>
      <Navbar.Section grow>
        <Group className={classes.header} position="apart">         
          <Code sx={{ fontWeight: 700 }}>0.1</Code>
        </Group>
        {items}
      </Navbar.Section>
     
{/* Bottom section Here \/ */}

      <Navbar.Section className={classes.footer}>
        <a href="#" className={classes.item} onClick={(event) => event.preventDefault()}>
          <IconSwitchHorizontal className={classes.linkIcon} stroke={1.5} />
          <span>Change account</span>
        </a>

        <a href="#" className={classes.item} onClick={(event) => event.preventDefault()}>
          <IconLogout className={classes.linkIcon} stroke={1.5} />
          <span>Logout</span>
        </a>
      </Navbar.Section>
    </Navbar>
  );
}

Layout代码

import { NavbarSimple } from "./Navbar/Navbar";

export default function Layout({ children }) {
    return (
      <>
        <NavbarSimple />
        <main>{children}</main>
          
      </>
    )
  }

我曾尝试使用Mantine的AppShell组件放置Navbar,但不确定如何实现页面切换,且使用时会导致整页重渲染,因此改用Next.js Layout,但仍未解决布局问题。


解决方法

方式1:用Flexbox改造现有Layout

问题根源是Fragment包裹的元素默认是块级垂直排列,给外层容器添加flex布局即可让侧边栏和主内容横向排列:

export default function Layout({ children }) {
  return (
    <div style={{ display: "flex", minHeight: "100vh" }}>
      <NavbarSimple />
      <main style={{ flex: 1, padding: "md" }}>{children}</main>
    </div>
  );
}
  • display: flex 让子元素横向排列
  • flex: 1 让主内容占满剩余空间
  • minHeight: 100vh 确保布局撑满视口高度

方式2:正确使用Mantine AppShell(解决重渲染问题)

之前用AppShell导致整页重渲染,是因为状态管理和页面切换的写法有误,正确用法如下:

  1. 改造AppShell布局:
import { AppShell } from "@mantine/core";
import { NavbarSimple } from "./Navbar/Navbar";

export default function AppShellLayout({ children }) {
  return (
    <AppShell
      navbar={<NavbarSimple />}
      navbarWidth={{ sm: 220, md: 280 }}
      padding="md"
    >
      <AppShell.Main>{children}</AppShell.Main>
    </AppShell>
  );
}
  1. 优化Navbar的active状态判断(用Next.js路由替代手动state):
import { usePathname } from "next/navigation"; // 导入路由钩子

export function NavbarSimple() {
  const { classes, cx } = useStyles();
  const pathname = usePathname(); // 获取当前路由路径

  const items = data.map((item) => (   
    <Link href={item.link} passHref style={{textDecoration: 'none'}}>
      <NavLink
        style={{ textDecoration: 'none' }}
        key={item.label}     
        active={pathname === item.link} // 用当前路径判断激活状态
        label={item.label}
        icon={<item.icon size={16} stroke={1.5} />}
      />   
    </Link>
  ));

  // 其余代码保持不变...
}

这样页面切换时只会更新AppShell.Main里的内容,不会触发整页重渲染,同时active状态判断更准确。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:52:55