如何在Next.js+MongoDB中实现SEO友好标题URL并通过ID查询
如何在Next.js中使用SEO友好的标题URL同时通过MongoDB的_id查询文档?
1. 生成SEO友好的Slug
先写一个工具函数,把帖子标题转换成适合URL的格式(小写、替换空格为连字符、移除特殊字符):
function generateSlug(title) { return title .toLowerCase() .replace(/[^a-z0-9]+/g, '-') // 将非字母数字的字符替换为连字符 .replace(/^-+|-+$/g, ''); // 移除开头和结尾的多余连字符 }
2. 修改首页的链接生成逻辑
在index.js里,用生成的slug结合_id构造SEO友好的URL,同时保留_id用于后续查询:
<div> {data.map((myData) => { const slug = generateSlug(myData.title); // 构造格式为「slug-_id」的URL const url = `/${slug}-${myData._id.toString()}`; return ( <h2 key={myData._id}> <Link href={url}> <a>{myData.title}</a> </Link> </h2> ); })} </div>
3. 更新getStaticPaths生成所有路径
在[posts].js的getStaticPaths中,为每个帖子生成包含slug和_id的路径:
export async function getStaticPaths() { const { db } = await connectToDatabase(); const data = await db.collection("posts").find().toArray(); const paths = data.map((myData) => { const slug = generateSlug(myData.title); const postId = myData._id.toString(); return { params: { postPage: `${slug}-${postId}` } }; }); return { paths, fallback: false }; }
4. 在getStaticProps中提取_id并查询文档
从路径参数里拆分出_id(URL格式是「slug-_id」,取最后一段即可),再用这个_id查询MongoDB:
export async function getStaticProps(context) { const postPage = context.params.postPage; // 拆分出_id部分 const postId = postPage.split('-').pop(); const { db } = await connectToDatabase(); const posts = await db .collection("posts") .find({ "_id": new ObjectID(postId) }) .toArray(); return { props: { post: posts[0] } }; }
可选优化
- 可以把生成好的slug直接存在MongoDB的文档里,避免每次重复计算,提升性能;
- 如果担心标题重复导致slug冲突,可以在slug后追加随机字符串,或者确保发布的标题唯一。
内容的提问来源于stack exchange,提问作者Tribe56123
相关产品推荐
相关产品推荐

