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

Vercel部署预渲染页面报错:fetch失败,求助排查

问题解决:Vercel部署时预渲染页面fetch失败的TypeError

核心问题分析

  1. 环境变量未适配生产环境:本地env.local里的NEXT_PUBLIC_BASE_URL设为http://localhost:3000/,部署到Vercel时未替换为线上域名,预渲染阶段(getStaticProps运行时)尝试访问本地地址,而Vercel构建环境无法解析localhost,触发fetch failed错误。
  2. 冗余的HTTP请求:在getStaticProps中通过HTTP调用自身API路由完全没必要,直接调用Sanity数据获取逻辑更可靠,还能避免URL拼接错误。

解决方案

方案1:快速修正环境变量配置

  • 登录Vercel控制台,进入目标项目 → Settings → Environment Variables
  • 添加生产环境变量NEXT_PUBLIC_BASE_URL,值为你的Vercel项目线上域名(例如https://your-project.vercel.app,注意不要带末尾斜杠)
  • 重新执行部署命令,确保构建时使用线上地址

方案2:跳过API路由,直接调用Sanity客户端(最优解)

这种方式彻底规避URL相关问题,同时提升构建效率:

  1. 抽离Sanity通用逻辑
    在lib/sanity.ts中创建客户端和数据获取函数:

    // lib/sanity.ts
    import { createClient } from '@sanity/client';
    
    const client = createClient({
      projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
      dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
      apiVersion: '2023-10-01', // 使用最新稳定API版本
      useCdn: false, // 构建阶段禁用CDN,确保获取实时数据
    });
    
    // 获取页面信息
    export async function getPageInfo() {
      const query = `*[_type == "pageInfo"][0]`;
      return await client.fetch(query);
    }
    
    // 同理添加其他数据获取函数
    export async function getExperience() {
      const query = `*[_type == "experience"] | order(dateStarted desc)`;
      return await client.fetch(query);
    }
    
    export async function getSkills() {
      const query = `*[_type == "skill"]`;
      return await client.fetch(query);
    }
    
  2. 修改数据获取函数
    替换原fetchPageInfo.js等文件的HTTP请求逻辑:

    // fetchPageInfo.js
    import { getPageInfo } from '../lib/sanity';
    
    export const fetchPageInfo = async () => {
      return await getPageInfo();
    };
    
  3. 更新getStaticProps
    直接调用抽离的函数,无需HTTP请求:

    // index.tsx
    import { getPageInfo, getExperience, getSkills, getProjet, getSocial } from '../lib/sanity';
    
    export const getStaticProps: GetStaticProps<Props> = async () => {
      const pageInfo: PageInfo = await getPageInfo();
      const experience: Experience[] = await getExperience();
      const skills: Skill[] = await getSkills();
      const projets: Projet[] = await getProjet();
      const socials: Social[] = await getSocial();
    
      return {
        props: {
          pageInfo,
          experience,
          skills,
          projets,
          socials,
        },
        revalidate: 10,
      };
    };
    

额外排查点

  • 若出现undefined/api/getExperience错误,检查Vercel环境变量是否配置正确,变量名拼写是否无误(注意大小写)
  • 给fetch添加错误捕获,便于定位问题:
    export const fetchPageInfo = async() => {
      try {
        // 自动移除末尾斜杠,避免路径拼接错误
        const baseUrl = process.env.NEXT_PUBLIC_BASE_URL?.replace(/\/$/, '');
        const res = await fetch(`${baseUrl}/api/getPageInfo`);
        if (!res.ok) throw new Error(`请求失败:${res.status}`);
        const data = await res.json();
        return data.pageInfo;
      } catch (err) {
        console.error('获取页面信息失败:', err);
        throw err; // 让Next.js终止构建并抛出错误
      }
    };
    

内容的提问来源于stack exchange,提问作者Théo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:21:02