Next.js App Router中如何为[slug]页面添加动态元数据?
实现动态元数据的步骤
在Next.js App Router中,你可以通过generateMetadata函数来生成动态页面元数据,以下是针对你的场景的具体实现:
1. 调整页面组件逻辑
移除页面顶部的'use client'标记(如果有客户端交互需求,比如ReactQuill这类组件,可以单独抽成客户端组件),因为generateMetadata需要在服务器端运行以保证SEO效果。
2. 编写generateMetadata函数
这个函数会接收路由参数params(包含当前文章的slug),你可以在这里通过slug从Firestore或API获取对应文章数据,再返回符合需求的元数据。
3. 完整代码示例
import { Metadata } from 'next'; import dynamic from 'next/dynamic'; import ArticleHeader from '@/app/components/articleHeader'; import { firestore } from '../../../../firestore'; import { collection, query, where, getDocs } from 'firebase/firestore'; import 'react-quill/dist/quill.snow.css'; // 将ReactQuill抽为独立客户端组件 const ReactQuill = dynamic(() => import('react-quill'), { ssr: false }); type BlogPost = { title: string; description: string; image?: string | null; content: string; slug: string; tags: Array<{ name: string }>; }; // 公共函数:根据slug获取文章数据 async function getBlogPostBySlug(slug: string): Promise<BlogPost | null> { const q = query(collection(firestore, 'blogPosts'), where('slug', '==', slug)); const querySnapshot = await getDocs(q); return querySnapshot.docs[0]?.data() as BlogPost || null; } // 生成动态元数据 export async function generateMetadata({ params }: { params: { slug: string } }): Promise<Metadata> { const post = await getBlogPostBySlug(params.slug); if (!post) { return { title: '文章不存在', description: '抱歉,你访问的文章不存在' }; } return { title: post.title, description: post.description, openGraph: { title: post.title, description: post.description, images: post.image ? [post.image] : [], type: 'article' } // 可按需添加更多元数据,比如twitterCard、keywords等 }; } // 页面主组件 const ArticlePage = async ({ params }: { params: { slug: string } }) => { const post = await getBlogPostBySlug(params.slug); if (!post) { return <div>文章不存在</div>; } return ( <div> <ArticleHeader title={post.title} description={post.description} /> <ReactQuill value={post.content} readOnly={true} theme="snow" /> </div> ); }; export default ArticlePage;
关键说明
generateMetadata是App Router内置的元数据生成函数,仅在服务器端执行,能确保搜索引擎抓取到正确的页面元数据。- 将文章数据获取逻辑抽为公共函数,避免在元数据生成和页面渲染中重复编写代码。
- 若页面需要客户端交互逻辑,只需将交互相关代码放在标记了
'use client'的独立组件中即可,不影响元数据的服务器端生成。
内容的提问来源于stack exchange,提问作者Burner
相关产品推荐
相关产品推荐

