需求背景:根据每次打开列表详情的标题修改浏览器的标签的title。
react版本:18
next版本:14.1.0
以下是官网的2种方式,nextjs官网generateMetadata定位
import { Metadata } from 'next'
// either Static metadata
export const metadata: Metadata = {
title: '...',
}
// or Dynamic metadata
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
静态修改浏览器标签title
import { Metadata } from 'next'
// 使用时需要注意页面要多套一层,在page.tsx的同级新建page.client.tsx
// 在page.tsx中引入
import PageClient from "./page.client";
export const metadata: Metadata = {
title: '...',
}
export default async function Page() {
return <PageClient />;
}
动态修改浏览器标签title(官网是在generateMetadata放了请求),以下是请求放在page里面
// 记录一下,下次遇到这种需求可以直接 cv
import PageClient from "./page.client";
// 定义元数据类型
interface MetaData {
title: string;
description?: string;
}
class metaTitle {
private events: { [eventName: string]: Array<(data: MetaData) => void> } = {};
// 订阅
on(eventName: string, callback: (data: MetaData) => void) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
// 取消订阅
off(eventName: string, callback: (data: MetaData) => void) {
if (this.events[eventName]) {
const eventIndex = this.events[eventName].indexOf(callback);
if (eventIndex !== -1) {
this.events[eventName].splice(eventIndex, 1);
}
}
}
// 发布
emit(eventName: string, data: MetaData) {
if (this.events[eventName]) {
this.events[eventName].forEach((callback: (arg: MetaData) => void) => {
callback(data);
});
}
}
// 设置元数据,数据类型明确
setMetaData(data: MetaData) {
this.emit('metatitle', data);
}
// 获取元数据,使用Promise封装异步逻辑
getMetaData(): Promise<MetaData> {
return new Promise((resolve) => {
const callback = (data: MetaData) => {
resolve(data);
this.off('metatitle', callback);
};
this.on('metatitle', callback);
});
}
}
const eventMetaTitle = new metaTitle();
export async function generateMetadata() {
return await eventMetaTitle.getMetaData();
}
export default async function Page(props: { searchParams: { id: string; }; }) {
const { data } = await fetch(`https://.../${props.searchParams.id}`).then((res) => res.json());
eventMetaTitle.setMetaData({
title: `title-${data.title}`,
description: data?.description || ""
})
return <PageClient data={data} />;
}
这里说一下nextjs文档一定要看英文的,中文更新太慢了有一些废弃了的没有更新到