You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js对接Firestore集合实现服务端渲染动态路由的问题求助

问题排查与实现方案

现有代码核心问题

  • 动态路由参数名不匹配:
    • 你的API路由文件名为pages/api/[doc].js,框架会自动将路径参数挂载到req.query.doc,你代码中写的req.query.name无法拿到正确的文档ID
    • 你的页面文件名为pages/[shoal].jsx,路由参数会挂载到router.query.shoal,你代码中取router.query.name会得到undefined,导致请求路径错误
  • 现有实现为客户端渲染(CSR),不符合你要求的服务端渲染(SSR)需求:用SWR拉取数据的逻辑在客户端执行,首屏会出现Loading状态,无法被搜索引擎直接爬取内容

正确SSR实现方案(无需额外API路由)

直接在页面的getServerSideProps中查询Firestore,服务端直出渲染结果,性能更高且符合SSR要求:

第一步:修改页面文件命名

将页面文件改名为pages/[doc].jsx,匹配你要的test.com/[文档ID]访问路径

第二步:编写页面代码

// 请先确保你已经正确初始化了服务端可用的Firestore db实例
import db from '你的Firestore初始化文件路径'

function Doc({ docData }) {
  return (
    <div>
      <p>Title: {docData.title}</p>
    </div>
  )
}

export async function getServerSideProps(context) {
  // 路由参数和文件名保持一致,所以取context.params.doc
  const docId = context.params.doc
  const docSnapshot = await db.collection("docs").doc(docId).get()
  
  // 文档不存在返回404
  if (!docSnapshot.exists) {
    return {
      notFound: true
    }
  }

  return {
    props: {
      docData: docSnapshot.data()
    }
  }
}

export default Doc

如果你坚持使用原有SWR方案的修复方法

  • 修改pages/api/[doc].js代码:
    export default (req, res) => {
      db.collection("docs")
        // 把req.query.name改成req.query.doc
        .doc(req.query.doc)
        .get()
        .then((doc) => {
          if (!doc.exists) return res.status(404).json({ error: '文档不存在' })
          res.json(doc.data());
        })
        .catch((error) => {
          res.status(500).json({ error });
        });
    };
    
  • 修改pages/[shoal].jsx代码:
    import { useRouter } from "next/router";
    import useSWR from "swr";
    
    const fetcher = async (...args) => {
      const res = await fetch(...args);
      if (!res.ok) throw new Error('请求失败')
      return res.json();
    };
    
    function Doc() {
      const router = useRouter();
      // 把name改成shoal,和文件名保持一致
      const { shoal } = router.query;
      const { data, error } = useSWR(shoal ? `/api/${shoal}` : null, fetcher);
    
      if (error) return "文档加载失败";
      if (!data) return "Loading...";
    
      return (
        <div>
          <p>Title: {data.title}</p>
        </div>
      );
    }
    
    export default Doc;
    

内容的提问来源于stack exchange,提问作者jl98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 11:57:03