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

Next.js博客动态目录本地正常,部署Vercel报TypeError求助

解决Next.js部署Vercel时出现TypeError: Cannot read properties of undefined (reading 'content')

问题原因

本地运行正常但Vercel部署报错,核心原因有三点:

  1. GraphQL客户端未配置API端点:代码中const graphcms = new GraphQLClient();未传入GraphCMS的API地址,本地依赖环境变量但Vercel未配置,导致查询失败返回post: undefined。
  2. 未处理post为空的情况:当fallback: true时,访问未预生成的slug会触发增量静态生成,此时可能查询不到对应post;或GraphQL查询返回null,直接访问post.content会触发未定义错误。
  3. 内容处理逻辑执行时机错误:newContent的计算在router.isFallback判断之前,即使处于加载状态也会执行processSync(post.content.html),此时post为空就会报错。

解决方案

1. 修复GraphQLClient初始化

添加API端点,使用环境变量配置(需在Vercel控制台设置对应环境变量):

// 替换为你的GraphCMS API地址,通过环境变量注入
const graphcms = new GraphQLClient(process.env.GRAPHCMS_API_URL);

2. 在getStaticProps中处理查询失败的情况

捕获错误并返回404,避免传递空的post给组件:

export async function getStaticProps({ params }) {
  const slug = params.slug;
  try {
    const data = await graphcms.request(QUERY, { slug });
    const post = data.post;
    
    // 未找到对应文章时返回404
    if (!post) {
      return { notFound: true };
    }

    return {
      props: { post },
    };
  } catch (error) {
    console.error("获取文章失败:", error);
    return { notFound: true };
  }
}

3. 调整组件内逻辑执行顺序

先判断加载状态和post是否存在,再执行内容处理:

export default function BlogPost({ post }) {
  const router = useRouter();

  // 优先处理加载状态或post为空的情况
  if (router.isFallback || !post) {
    return <h2>Loading</h2>;
  }

  let toc = [];

  const newContent = unified()
    .use(rehypeParse, { fragment: true })
    .use(() => (tree) => {
      visit(tree, "element", (node) => {
        if (node.tagName === "h2") {
          // 额外判断标题内容是否存在,避免空值报错
          if (!node.children[0]?.value) return;
          
          const id = parameterize(node.children[0].value);
          node.properties.id = id;
          toc.push({ id, title: node.children[0].value });
        }
      });
    })
    .use(rehypeStringify)
    .processSync(post.content.html)
    .toString();

  return (
    <div>
      <header>
        <h1>{post.title}</h1>
        <img
          src={post.coverPhoto.url}
          width="100%"
          style={{ borderRadius: "1rem" }}
        />
        <span>Published: {post.datePublish}</span>
      </header>
      <main>
        <div>
          {toc.map((item) => (
            <li style={{ listStyle: "none" }} key={item.id}>
              <a style={{ fontSize: "1.1rem" }} href={`#${item.id}`}>
                <b> {item.title}</b>
              </a>
            </li>
          ))}
        </div>
        <div
          className="blogpost"
          dangerouslySetInnerHTML={{ __html: newContent }}
        />
      </main>
    </div>
  );
}

4. 配置Vercel环境变量

在Vercel项目的「Settings」→「Environment Variables」中添加GRAPHCMS_API_URL,值与本地.env文件中的一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:18:05