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

Next.js公共动态头部实现求助:_app.js中getServerSideProps无效

解决Next.js _app.js无法用getServerSideProps获取动态导航数据的问题

Next.js的_app.js(Pages Router)确实不支持getServerSideProps,这是框架的限制,给你几个实际可行的解决办法:

方法一:在Header组件内用SWR/React Query做客户端数据获取

直接把导航数据的获取逻辑放到Header组件里,用数据请求库来处理,既能缓存数据,还能处理加载、错误状态。以SWR为例:

首先安装SWR:

npm install swr

然后修改Header组件:

import useSWR from 'swr'

// 定义数据请求函数
const fetcher = async (url) => {
  const res = await fetch(url)
  if (!res.ok) throw new Error('Failed to fetch navigation items')
  return res.json()
}

export default function Header() {
  const { data: navItems, error, isLoading } = useSWR('/api/nav-items', fetcher)

  if (isLoading) return <div>Loading navigation...</div>
  if (error) return <div>Failed to load navigation</div>

  return (
    <header>
      <nav>
        {navItems.map(item => (
          <a key={item.id} href={item.path}>{item.name}</a>
        ))}
      </nav>
    </header>
  )
}

这里需要你写一个/api/nav-items的API路由,用来从数据库查询导航数据返回给前端。这种方式的好处是不用改动_app.js的结构,数据缓存、重新验证都由SWR自动处理。

方法二:在_app.js中使用getInitialProps(Pages Router专属)

_app.js虽然不支持getServerSideProps,但支持getInitialProps,可以在这里一次性获取导航数据,然后传递给所有页面和Header组件:

修改_app.js:

import Header from '../components/Header'

function MyApp({ Component, pageProps, navItems }) {
  return (
    <>
      <Header navItems={navItems} />
      <Component {...pageProps} />
    </>
  )
}

MyApp.getInitialProps = async (appContext) => {
  // 这里调用数据库查询逻辑,比如从MongoDB/MySQL获取导航数据
  const navItems = await fetchNavItemsFromDB()
  
  // 获取页面本身的props
  const appProps = await App.getInitialProps(appContext)

  return { ...appProps, navItems }
}

export default MyApp

然后Header组件直接接收navItems props渲染即可:

export default function Header({ navItems }) {
  return (
    <header>
      <nav>
        {navItems.map(item => (
          <a key={item.id} href={item.path}>{item.name}</a>
        ))}
      </nav>
    </header>
  )
}

注意:getInitialProps在Next.js 13+的App Router里已经废弃,只适用于Pages Router项目。

方法三:如果用Next.js 13+ App Router,改用Root Layout

如果你已经升级到App Router,直接在根布局(app/layout.js)里用异步函数获取数据就行,因为App Router支持组件内的异步数据获取,根布局会被所有页面共享:

修改app/layout.js:

import Header from './components/Header'

// 根布局可以是async函数
export default async function RootLayout({ children }) {
  // 直接在这里从数据库获取导航数据
  const navItems = await fetchNavItemsFromDB()

  return (
    <html lang="en">
      <body>
        <Header navItems={navItems} />
        {children}
      </body>
    </html>
  )
}

Header组件同样接收navItems渲染,这种方式是App Router推荐的做法,简单直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:05:14