开发者问题收集

如何使用 Next.js 中带有应用路由器的客户端组件更改页面标题?

2023-06-09
11245

我正在使用 Next.js 构建博客,并使用新的应用路由器进行导航。但是,我遇到了一个问题,即每个博客页面都显示相同的标题和说明。 在调查代码后,我发现标题和说明是从 layout.js 文件中导出为 Metadata() 的,这似乎是问题的主要原因。当我尝试在单个博客页面中使用 Metadata() 时,它没有按预期工作。

有没有办法解决这个问题,并为每个博客页面设置不同的标题和说明, 即使在使用应用路由器并包含非 SSR 页面(如客户端)时也是如此? 我将不胜感激有关如何解决此问题的任何指导或建议。

3个回答

如果您的页面标题是静态的,那么您可以创建一个新的 layout.js 文件来导出带有新标题的元数据。

.
├── app/
│   ├── client/
│   │   ├── layout.js // Create new title here
│   │   └── page.js // 'use client'
│   ├── layout.js
│   └── page.js
├── package.json
└── next.config.js

因此在上面的例子中,如果 client/page.js 有一个 'use client' 指令,那么您可以通过创建一个兄弟 layout.js 文件来更改页面标题,该文件只是呈现子项并更新标题:

client/layout.js

export const metadata = {
  title: 'New Title'
}
export default function ClientLayout({ children }) {
  return children
}

如果页面标题基于来自 API 的动态内容,那么您可以将上述方法用于默认的服务器端实现,然后在呈现 client/page.js 时更新 useEffect 内的 document.title

morganney
2023-08-19

在 Next.js 13 中,您可以通过从任何 layout.js 或 page.js 文件 导出 Metadata 对象 来定义静态元数据,但您可能希望为每个页面生成动态元数据(取决于该页面所获取内容的元数据)。 要执行动态元数据,您需要 导出 generateMetadata 函数

您还可能会发现使用像 next-seo 这样的包更容易,尽管我从 Next.js 12 开始就没有使用过它,也不知道它是否适用于新的应用程序目录。

Aymeric Wilke
2023-06-13

我的方式: AppPage.tsx

'use client'
const AppPage = ({ title, children, className, ...rest }) => {
  useEffect(() => {
    if (title) document.title = title
  }, [title])
  return <div className={className}>{children}</div>
}

handycode
2023-09-17