6

I got this error during Vercel deployment:

TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11457:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  cause: Error: connect ECONNREFUSED 127.0.0.1:3000
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)
      at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
    errno: -111,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '127.0.0.1',
    port: 3000
  }
}
Error occurred prerendering page "/match". Read more: https://nextjs.org/docs/messages/prerender-error
TypeError: fetch failed
    at Object.fetch (node:internal/deps/undici/undici:11457:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

I guess probably is because of the http://localhost:3000/api/event, how can I replace a correct url to localhost?

async function getData(): Promise<Events[]> {
  const data = await fetch(`http://localhost:3000/api/event`, {
    cache: "no-cache",
  }).then((res) => res.json());
  return data;
}
1

8 Answers 8

8

This error occurs if you try to call your internal API route from a server component at build time, where there is no application running (the application being build and not deployed yet). Tim Neutkens from Next.js points that out on a GitHub issue with a similar error:

This is because you're trying to fetch from an internal api route during build, which is not supported.

Instead of calling the internal API route from a server component, which then calls your DB or CMS, reach them directly from the component. It helps avoid the error, and also an additional useless API call.


That has been said, if the API is not your internal one, you can replace

fetch('http://localhost:3000/api/event')

with

fetch(process.env.URL + '/api/even')

and create an .env file in which you add:

URL=http://localhost:3000

Then on the Vercel dashboard, you set an URL environment variable with your production URL.

Sign up to request clarification or add additional context in comments.

Comments

1

This error is likely occurring due to the usage of the http://localhost:3000/api/event URL in your code when deploying to Vercel. When your application is in deployment mode, the localhost address no longer refers to your own system, and you should use the actual server address where your API resides.

To resolve this issue, it's better to use environment variables to determine the API address. In development and testing environments, you can use http://localhost:3000, but when deploying to Vercel, you should use the Vercel server's address to access the API.

For example, you can utilize environment variables within Vercel. First, define environment variables in your Vercel settings. Create an environment variable named NEXT_PUBLIC_API_URL and set its value to your API address (e.g., https://your-api-domain.com).

Then, in your code, use the NEXT_PUBLIC_API_URL environment variable for API communication:

async function getData(): Promise<Events[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL; // Using an environment variable
  const data = await fetch(`${apiUrl}/api/event`, {
    cache: "no-cache",
  }).then((res) => res.json());
  return data;
}

With these changes, your application should be able to correctly communicate with the API in all environments (development, testing, deployment), and the ECONNREFUSED error should be resolved.

Comments

1

The same thing happened to me

Next 14.1

it doesn't matter if you use 127.0.0.1 or localhost, it works both ways in fecth() I don't use cache:'no-store', only route. The route (route.js) and the page (page.js) have to be dynamic.

The solution is to add this line in both files:

export const dynamic = 'force-dynamic';

TypeScript I have not tested

Comments

0

This problem was resolved by substituting localhost with 127.0.0.1.

More details can be found in the related GitHub discussion.

Comments

0

In my case

my Data Fetching function is like that

enter image description here

my .env is like that

enter image description here

now when i run npm run build it showing following error while i am developing the application.

enter image description here

my server is running on localhost:3000

so the error is because i am using external api if we make same hostname like localhost then the issue will be resolved.

for example i create api with same response on http://localhost:4000/todos so its working fine.

enter image description here

Comments

0

face the same issue with that solution is add this line in file

***export const dynamic = 'force-dynamic';***

Next 14.1

1 Comment

Is this answer any different from this older answer already provided by @Juan? If so, how does it differ? (Also, does the code in your answer really need those asterisks?)
0

In my case, the problem is resolved using the use effect for fetching the data instead of directly fetching the data, and put the component on the client side.

For the documentation read the official Nextjs docs on use effects.

I also put the code snippet to give you a better idea of what my problem was and how I solved it.

This is an example of how I fetch the data from the backend

import { BACKEND_URL } from "./constants";

export async function fetchYoutubeVideos() {
  try {
    console.log(`${BACKEND_URL}home/api/youtube-video`);

    const res = fetch(`${BACKEND_URL}home/api/youtube-video`);

    return (await res).json();
  } catch (error) {
    console.error("Error fetching profile:", error);
  }
}

Then I was calling this method directly in my component like this

async function YouTubeVideosComponent() {
  const youtubeVideos = await fetchYoutubeVideos();

  return(<div className="grid grid-flow-col grid-rows-1 gap-4  p-4 overflow-x-scroll">
        {youtubeVideos.map((video, index) => (
          <div key={index} className="youtube-video-card w-full">
            <YoutubeVideoCard name={video.name} embedUrl={video.embed_url} />
          </div>
        ))}
      </div>);
}

This fetching data will cause a dynamic server error.

To solve the issue I have added "use client"; literal to my component to enable the usage of useEffect and useState hooks, imported hooks import { useEffect, useState } from "react"; and changed my fetch data strategy in the component like this

"use client";
import { fetchYoutubeVideos } from "../data/fetch_youtube_video";
import { useEffect, useState } from "react";

function YouTubeVideosComponent() {
  const [youtubeVideos, setYoutubeVideos] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const videos = await fetchYoutubeVideos();
        setYoutubeVideos(videos || []);
      } catch (err) {
        console.error("Error fetching YouTube videos:", err);
        setError("Failed to load YouTube videos.");
      } finally {
        setLoading(false);
      }
    }

    fetchData();
  }, []); // Empty dependency array to run only once on mount

return(...);
}

Now the data is fetched at run time and the build goes well.

Comments

-1

just put that on your root Layout file

export const dynamic = "force-dynamic";
export const fetchCache = "force-no-store";

1 Comment

You probably do not want to force your entire site to be dynamically rendered. This has side effects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.