Next.js 如何实现路由 URL 美化并保持基于 ID 查询 API 数据
实现方案
这个需求在Next.js中完全可以实现,核心思路是新增唯一的slug字段映射经销商ID,通过动态路由匹配字符串路径,底层仍用ID完成数据库查询,具体实现步骤如下:
前置准备
首先给你的crm_dealers数据表新增一个唯一非空的slug字段,存储 sacramento-ca这类格式化的地址字符串,保证每个经销商的slug不重复。
方案1:沿用现有服务端渲染(getServerSideProps)逻辑
步骤1:调整动态路由文件名
把原有经销商详情页的文件名从pages/dealers/[id].tsx改为pages/dealers/[slug].tsx,此时Next.js会自动匹配/dealers/xxx格式的路径。
步骤2:修改单经销商查询API逻辑
调整getSingleDealer.ts的查询逻辑,兼容数字ID和字符串slug两种查询条件:
import Cors from 'cors'; import { prisma } from 'lib/prisma'; import { NextApiResponse, NextApiRequest, NextApiHandler } from 'next'; const cors = Cors({ methods: ['GET', 'HEAD'], }); function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: any) { return new Promise((resolve, reject) => { fn(req, res, (result: any) => { if (result instanceof Error) { return reject(result); } return resolve(result); }); }); } const getDealer: NextApiHandler = async (req: NextApiRequest, res: NextApiResponse) => { await runMiddleware(req, res, cors); const queryParam = req.query.param as string; let dealer; // 判断参数是数字ID还是字符串slug if (/^\d+$/.test(queryParam)) { dealer = await prisma.crm_dealers.findUnique({ where: { id: Number(queryParam) } }) } else { dealer = await prisma.crm_dealers.findFirst({ where: { slug: queryParam } }) } if (!dealer) return res.status(404).send({ message: '经销商不存在' }) res.status(200).send({ dealer, method: req.method }); }; export default getDealer;
步骤3:调整getServerSideProps逻辑
现在路由参数变为slug,直接传递给API即可,同时增加404兜底逻辑:
export const getServerSideProps = async ({ params }: Params) => { const { slug } = params; const { dealer } = await getSingleDealer('api/dealer', slug); if (!dealer) { return { notFound: true } } return { props: { dealer }, }; };
方案2:静态生成优化(可选)
如果你的经销商信息更新频率不高,可以改用getStaticPaths + getStaticProps做静态生成,访问速度更快:
- 在详情页添加
getStaticPaths方法,调用getAllDealers接口拿到所有经销商的slug,生成所有静态路径 getStaticProps中根据slug查询对应经销商信息,打包时预生成所有经销商页面
旧链接兼容(可选)
如果需要保留原来/dealers/[id]的访问路径,可以在next.config.js中添加重定向规则,把旧ID路径自动跳转到对应的slug路径,避免旧链接失效。
内容的提问来源于stack exchange,提问作者Jesse Winton
相关产品推荐
相关产品推荐

