如何在Next.js中动态设置页面标题(服务端/客户端组件场景)
Next.js 动态设置页面 Metadata(标题)
在 Next.js 中,要结合服务端数据动态设置 Metadata,主要有两种适配不同场景的方案:
方案一:使用动态 Metadata 函数(服务端组件页面首选)
把原本的静态 metadata 对象改成异步函数,在函数内部获取服务端数据后,返回动态生成的 Metadata。
以商品详情页(路由示例:app/products/[id]/page.tsx)为例:
import type { Metadata } from "next"; import { getProductById } from "@/lib/products"; // 自定义的服务端商品数据获取函数 // 异步生成 Metadata export async function generateMetadata({ params }: { params: { id: string } }): Promise<Metadata> { // 1. 根据路由参数获取商品数据 const product = await getProductById(params.id); // 2. 返回动态标题和描述 return { title: `${product.name} - 你的商城名称`, description: product.description || "精选优质商品,欢迎选购", }; } export default async function ProductPage({ params }: { params: { id: string } }) { const product = await getProductById(params.id); return ( <div> {/* 商品页面内容 */} <h1>{product.name}</h1> <p>{product.description}</p> </div> ); }
关键说明:
generateMetadata是 Next.js 专为服务端组件设计的动态 Metadata 生成函数,仅在服务端执行- 函数可接收
params(路由参数)、searchParams(查询参数)等上下文,方便获取动态标识 - 内部可直接调用服务端数据接口(数据库查询、API 请求等),无需额外处理异步逻辑
方案二:客户端侧动态修改标题(适用于纯客户端场景)
如果是客户端组件或通过客户端路由跳转后需要更新标题,可以直接操作浏览器的 document.title:
"use client"; import { useState, useEffect } from "react"; import { getProductById } from "@/lib/products"; export default function ProductClientPage({ params }: { params: { id: string } }) { const [product, setProduct] = useState(null); useEffect(() => { async function fetchAndUpdateTitle() { const productData = await getProductById(params.id); setProduct(productData); // 客户端更新页面标题 document.title = `${productData.name} - 你的商城名称`; } fetchAndUpdateTitle(); }, [params.id]); if (!product) return <div>加载中...</div>; return ( <div> <h1>{product.name}</h1> <p>{product.description}</p> </div> ); }
注意:
- 这种方式仅在客户端生效,不利于 SEO(搜索引擎爬虫可能不会执行客户端 JS)
- 优先选择方案一,服务端生成的 Metadata 能被爬虫正确抓取,对 SEO 更友好
静态与动态 Metadata 对比
- 静态 Metadata:适合内容固定的页面(如首页、联系页),直接导出静态对象即可
- 动态 Metadata:适合内容随路由/数据变化的页面(如商品页、文章页),通过
generateMetadata异步函数生成
内容的提问来源于stack exchange,提问作者Hoomi
相关产品推荐
相关产品推荐

