GitHub Actions build fails when Next.js tries to prerender page that needs external API

Problem Overview

I’m working on a Next.js app that connects to an Express backend API. Everything runs perfectly on my development machine where both services are running in Docker containers. But when GitHub Actions tries to build my Next.js project for testing and linting, it crashes because the build process attempts to fetch data from my backend API which isn’t running during the CI pipeline.

Error Details

Here’s what happens when the action runs npm run build:

> [email protected] build  
> next build

   ▲ Next.js 15.3.3

   Creating an optimized production build ...
 ✓ Compiled successfully in 5.2s
 ✓ Linting and checking validity of types
 ✓ Collecting page data
Error occurred prerendering page "/dashboard". 
Error: getaddrinfo ENOTFOUND api-server
    at RequestHandler.execute (/app/.next/server/app/dashboard/page.js:1:445672)
    at ClientRequest.emit (node:events:518:28)
    at Socket.socketErrorListener (node:_http_client:518:5)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
Export encountered an error on /dashboard: /, exiting the build.
 ⨯ Next.js build worker exited with code: 1 and signal: null

Problematic Code

The issue stems from this server component that makes an API call during prerendering:

/* ProductGrid.tsx */

import fetch from 'node-fetch';
import ProductCard from './ProductCard';
import './ProductGrid.css';

interface Product {
  title: string,
  productId: number
};

export default async function ProductGrid() {
  const apiUrl = 'http://api-server:3001';
  const result = await fetch(`${apiUrl}/api/products/`); // Fails during CI build
  const products: Product[] = await result.json();

  return (
    <div className='product-container'>
      {products.map((product) => 
        <ProductCard title={product.title} id={product.productId} key={product.productId}/>
      )}
    </div>
  );
};

What I’ve Tried

I’ve attempted converting this to a client component, moving the fetch call to useEffect, and extracting the API logic into separate functions. Nothing works because the fundamental issue remains - there’s no API server available during the build step in GitHub Actions.

Potential Solutions

I think any of these approaches would fix my issue:

  1. Mock the API server during GitHub Actions so the fetch succeeds.
  2. Run both containers together in the CI environment.
  3. Force this page to skip prerendering completely.
  4. Disable prerendering for the whole application.

Has anyone dealt with this before? I’m using the App Router if that matters.

Had this exact problem six months ago when switching to App Router. The cleanest fix? Use Next.js dynamic rendering to stop those problematic pages from prerendering at build time. Just add export const dynamic = 'force-dynamic' to your dashboard page component. This tells Next.js to skip prerendering and render at request time instead. Drop it right in your page.tsx file next to your default export. Way simpler than mocking APIs or spinning up extra containers in CI. Performance hit is minimal since you’re only targeting pages that actually need external data, and it keeps the same behavior between dev and production. Been running this in production for months with zero issues.

Had this same issue six months ago. Easiest fix was using Next.js’s environment variable detection to handle API calls during build time. Check if process.env.NODE_ENV === 'production' and process.env.VERCEL is undefined (or whatever your GitHub Actions sets), then return mock data or an empty array instead of hitting the actual API. Your component still prerenders but with fallback data, and real API calls happen client-side after hydration. Wrap your fetch in try-catch and return sensible defaults when the API server’s down. Way simpler than setting up multiple containers in CI just for a build step that doesn’t need live data.

simple fix - just add output: 'export' in your next.config.js and handle api calls client-side only. you might lose some seo benefits but it’ll stop the build crashes. or you could wrap your fetch in try/catch, return an empty array when it fails, then load data after mount. it’s been working for me!

Had this exact problem last year on a project with the same frontend/backend dependency mess.

Your CI is overthinking the build phase. Don’t fight Next.js prerendering or mess with mock servers - automate it properly instead.

I moved everything to an automation platform that handles service dependencies cleanly. Set up workflows that spin up your Express API container first, wait for it to be healthy, then run the Next.js build. Your prerendering works just like it does locally.

Best part? You can add conditional logic that uses real API data when services are up, falls back to cached/mock data when they’re not. Zero code changes in your components.

I’ve used this approach on multiple projects and it kills all the environment-specific hacks. Your CI actually matches your local setup.

Latenode handles this workflow automation really well - way better than fighting GitHub Actions limitations: https://latenode.com