动态元数据
本课属于 Coddy React 学习旅程的“Next.js 基础”单元。第 15 课,共 47 课。
metadata 对象是常量,因此无法用于动态路由:app/dishes/[slug]/page.jsx 会在每个 URL 下显示不同的菜品,每个菜品都需要自己的标题。
为此,请改为导出一个函数:
export async function generateMetadata({ params }) {
const { slug } = await params;
return { title: DISHES[slug].name };
}它会获取页面所获取的相同 params(这是一个 promise,所以你需要 await 它),并返回与 metadata 对象相同的结构。在同一个文件中二选一,不要同时使用两者。
标题模板
每个页面的标题都重复显示网站名称,时间久了会让人厌烦。布局可以传递一个模式,而不是一个普通字符串:
// app/layout.jsx
export const metadata = {
title: {
default: 'Coddy Eats',
template: '%s | Coddy Eats',
},
};default:未设置标题的页面使用的标题template:已设置标题的页面使用的模式;页面标题会放在%s的位置
因此,返回 title: 'Margherita' 的页面最终会在标签页中显示为 Margherita | Coddy Eats,而没有设置任何内容的主页则会显示为 Coddy Eats。在布局中写一次品牌名称即可。
挑战
中等目前每个菜品页面的标签页都显示 Coddy Eats。为每个页面设置各自的标题。
在 app/dishes/[slug]/page.jsx 中,添加一个导出的 async 函数,名为 generateMetadata,它需要:
- 接收
{ params },并等待它以获取slug - 返回
{ title: DISHES[slug].name }
app/layout.jsx 中已经设置了模板 '%s | Coddy Eats',因此 /dishes/margherita 的标题最终应为 Margherita | Coddy Eats。看一下布局文件,你不需要修改它。
亲手试试
import './globals.css';
export const metadata = {
title: {
default: 'Coddy Eats',
template: '%s | Coddy Eats',
},
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。