部署至Vercel时遭遇预渲染错误,寻求技术排查方案
问题分析与解决方案
问题概述
构建基于WordPress(WPGraphQL插件)的无头Next.js站点时,本地运行及npm run build均正常,但Vercel自动部署阶段预渲染/how-it-works页面失败,抛出TypeError: Cannot read properties of undefined (reading 'toString')错误。
报错信息
} TypeError: Cannot read properties of undefined (reading 'toString') at /vercel/path0/.next/server/chunks/948.js:2:4371 at /vercel/path0/.next/server/chunks/948.js:2:15874 at a.with (/vercel/path0/.next/server/chunks/948.js:1:8878) at c.with (/vercel/path0/.next/server/chunks/948.js:1:3078) at c.startActiveSpan (/vercel/path0/.next/server/chunks/948.js:1:18133) at a.startActiveSpan (/vercel/path0/.next/server/chunks/948.js:1:18667) at /vercel/path0/.next/server/chunks/948.js:2:15407 at a.with (/vercel/path0/.next/server/chunks/948.js:1:8878) at c.with (/vercel/path0/.next/server/chunks/948.js:1:3078) at b.trace (/vercel/path0/.next/server/chunks/948.js:2:15361) { digest: '2509559086' } Error occurred prerendering page "/how-it-works". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: Cannot read properties of undefined (reading 'toString') at /vercel/path0/.next/server/chunks/948.js:2:4371 at /vercel/path0/.next/server/chunks/948.js:2:15874 at a.with (/vercel/path0/.next/server/chunks/948.js:1:8878) at c.with (/vercel/path0/.next/server/chunks/948.js:1:3078) at c.startActiveSpan (/vercel/path0/.next/server/chunks/948.js:1:18133) at a.startActiveSpan (/vercel/path0/.next/server/chunks/948.js:1:18667) at /vercel/path0/.next/server/chunks/948.js:2:15407 at a.with (/vercel/path0/.next/server/chunks/948.js:1:8878) at c.with (/vercel/path0/.next/server/chunks/948.js:1:3078) at b.trace (/vercel/path0/.next/server/chunks/948.js:2:15361) ✓ Generating static pages (7/7) > Export encountered errors on following paths: /(routes)/how-it-works/page: /how-it-works Error: Command "npm run build" exited with 1
引发问题的代码(app/(routes)/how-it-works/page.js)
import styles from "./page.module.scss"; async function getPage() { const query = ` query GetPostByUri { pageBy(uri: "distance-education/how-it-works/") { title content heroImage { heroImage { node { sourceUrl altText } } } } } `; const res = await fetch(process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT, { method: "POST", headers: { "Content-Type": "application/json", }, next: { revalidate: 5, }, body: JSON.stringify({ query }), }); const responseBody = await res.json(); if (responseBody && responseBody.data && responseBody.data.pageBy) { return responseBody.data.pageBy; } else { throw new Error("Failed to fetch the page"); } } export default async function HowItWorks() { const page = await getPage(); return ( <div className={styles.wrapper}> <h1 className={styles.title}>{page.title}</h1> {page.heroImage.heroImage ? ( <img src={page.heroImage.heroImage.node.sourceUrl} className={styles.heroImg} alt={page.heroImage.heroImage.node.altText} /> ) : ( <></> )} <div dangerouslySetInnerHTML={{ __html: page.content }} className={styles.content} /> </div> ); }
解决方案
1. 检查Vercel环境变量配置
- 确认
NEXT_PUBLIC_GRAPHQL_ENDPOINT已在Vercel项目的环境变量中正确设置,且值与本地一致 - 验证WordPress站点是否允许Vercel服务器IP访问(避免CORS或403错误导致数据获取失败)
2. 增加数据层级的可选链保护
生产环境中WPGraphQL返回的heroImage可能存在层级缺失(如page.heroImage为undefined),导致访问heroImage.heroImage时报错。修改渲染逻辑,使用可选链操作符?.避免崩溃:
{page.heroImage?.heroImage?.node ? ( <img src={page.heroImage.heroImage.node.sourceUrl} className={styles.heroImg} alt={page.heroImage.heroImage.node.altText || ''} /> ) : ( <></> )}
3. 调试生产环境数据返回
在getPage函数中添加日志,查看Vercel构建时的GraphQL响应内容:
async function getPage() { // ... 原有代码 const responseBody = await res.json(); // 添加日志 console.log('Production GraphQL Response:', JSON.stringify(responseBody)); if (responseBody && responseBody.data && responseBody.data.pageBy) { return responseBody.data.pageBy; } else { throw new Error("Failed to fetch the page"); } }
通过Vercel构建日志查看输出,确认是否存在数据缺失或结构不一致的情况。
4. 验证WordPress端数据一致性
- 确认
pageBy(uri: "distance-education/how-it-works/")中的路径在生产环境WordPress中存在 - 检查WPGraphQL是否能正常返回该页面的
heroImage字段数据(可能本地与生产环境内容不同步)
5. 调整预渲染策略
若页面数据存在动态性,可强制页面动态渲染,避免预渲染阶段报错:
在page.js顶部添加:
export const dynamic = 'force-dynamic';
内容的提问来源于stack exchange,提问作者Kent O'Sullivan
相关产品推荐
相关产品推荐

