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

NextJS 13 App Dir服务器组件构建报错,Vercel部署求助

Next.js 13 App Directory(Beta)部署Vercel时Fetch请求失败

问题背景

使用Next.js 13 Beta版App Directory功能+TypeScript开发站点,本地运行完全正常,所有fetch请求均能正常工作,但部署到Vercel时,CLI生成静态页面阶段fetch请求崩溃,4个服务器组件(About、WorkExperience、Skills、Projects)均报相同错误。

错误日志

(node:457) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time

(Use `node --trace-warnings ...` to show where the warning was created)
TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11118:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async fetchPageInfo (/vercel/path0/.next/server/app/page.js:664:20)
    at async About (/vercel/path0/.next/server/app/page.js:679:18) {
  cause: Error: connect ECONNREFUSED 127.0.0.1:3000
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16)
      at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
    errno: -111,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '127.0.0.1',
    port: 3000
  }
}

相关代码

page.tsx

import {
  Experience,
  PageInfo,
  Project,
  Skill,
  Social,
} from "@/pages/api/typings";

import About from "./Components/about";
import Contact from "./Components/contact";
import WorkExperience from "./Components/experience";
import Header from "./Components/header";
import Hero from "./Components/hero";
import Projects from "./Components/projects";
import Skills from "./Components/skills";

type Props = {
  pageInfo: PageInfo;
  experiences: Experience;
  skills: Skill[];
  projects: Project[];
  socials: Social[];
};

export default function Home() {
  return (
    <main className="h-screen snap-y snap-mandatory overflow-scroll bg-background z-0 scrollbar scrollbar-track-textColour scrollbar-thumb-menuColour">
      <Header />
      <section className="snap-center">
        <Hero />
      </section>
      <section className="snap-center" id="about">
        {/* @ts-expect-error Server Component */}
        <About />
      </section>
      <section className="snap-center" id="experience">
        {/* @ts-expect-error Server Component */}
        <WorkExperience />
      </section>
      <section className="snap-center" id="skills">
        {/* @ts-expect-error Server Component */}
        <Skills />
      </section>
      <section className="snap-start" id="projects">
        {/* @ts-expect-error Server Component */}
        <Projects />
      </section>
      <section className="snap-start" id="contact">
        <Contact />
      </section>
    </main>
  );
}

额外信息

  • About、WorkExperience、Skills、Projects为服务器组件,其余组件因使用状态标记为客户端组件
  • 已确认目录路径正确,所有.env变量已声明且可用
  • 尝试过VSCode CLI构建、GitHub Web UI构建,均未解决问题

解决方案

核心原因

部署阶段(静态生成)时,服务器组件中的fetch请求尝试访问127.0.0.1:3000,但此时本地服务器并未运行,导致连接被拒绝。本地运行时服务器已启动,所以请求正常。

修复步骤

  1. 直接调用数据逻辑,跳过本地API路由
    服务器组件可以直接执行数据获取逻辑(如数据库查询、第三方SDK调用),无需通过API路由中转。把API路由里的业务逻辑抽成独立函数,放在lib目录下,在服务器组件中直接调用该函数,替代fetch('http://localhost:3000/api/xxx')的写法。

  2. 用环境变量配置API地址(若必须保留API路由)
    在Vercel部署时,API的实际地址是站点域名,而非localhost。添加环境变量API_BASE_URL:

    • 本地开发时设为http://localhost:3000
    • Vercel部署时设为你的站点域名(如https://your-site.vercel.app)
      然后在fetch时使用process.env.API_BASE_URL + '/api/xxx'拼接地址。
  3. 遵循App Router数据获取规范
    Next.js 13 App Directory中,服务器组件支持直接用async/await在组件内部获取数据,确保数据获取逻辑在服务器端执行,避免依赖本地运行的开发服务器。

验证方法

本地执行next build命令测试,若构建成功,说明问题已修复,再部署到Vercel即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:50:26