admin管理员组

文章数量:1415476

Describe the bug

I have built an application with NextJS that has an internal API and I use the getStaticProps methods to query the API.

You can find the deployed app here: /

And also the github repository here: enter link description here

The application works perfectly in development mode and the deploy I made in Vercel also works. But when I run the next build mand I get the following error:

Build error occurred
FetchError: request to http://localhost:3000/api/restaurants failed, reason: connect ECONNREFUSED 127.0.0.1:3000
    at ClientRequest.<anonymous> (/home/silinde87/Jobs/tailor/TailorChallenge/node_modules/node-fetch/lib/index.js:1461:11)
    at ClientRequest.emit (node:events:376:20)
    at Socket.socketErrorListener (node:_http_client:474:9)
    at Socket.emit (node:events:376:20)
    at emitErrorNT (node:internal/streams/destroy:188:8)
    at emitErrorCloseNT (node:internal/streams/destroy:153:3)
    at processTicksAndRejections (node:internal/process/task_queues:80:21) {
  type: 'system',
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED'
}
info  - Collecting page data .npm ERR! code 1
npm ERR! path /home/silinde87/Jobs/tailor/TailorChallenge
npm ERR! mand failed
npm ERR! mand sh -c next build 

NextJS internal API

/api/restaurants/index.js

export default function handler(req, res) {
    const { method } = req;
    
    switch (method) {
        case 'GET':
            getRestaurants();
            break;
        default:
            res.status(405).end(`Method ${req.method} Not Allowed`);
    }

    function getRestaurants() {
        const restaurants = data;
        res.status(200).json(restaurants);
    }
}

/api/restaurants/[id].js

export default function handler(req, res) {
    const { id } = req.query;
    const { method } = req;

    switch (method) {
        case 'GET':
            getRestaurantById();
            break;
        default:
            res.status(405).end(`Method ${req.method} Not Allowed`);
    }

    function getRestaurantById() {
        const restaurants = data.find((el) => el.id.toString() === id.toString());
        if (restaurants) res.status(200).json(restaurants);
        else res.status(405).end(`There is no Restaurant with id: ${id}`);
    }
}

Pages from NextJS

pages/index.js <-- Where I fetch the restaurants list

export async function getStaticProps() {
    const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants`);
    const restaurants = await res.json();

    if (!restaurants) {
        return {
            notFound: true,
        };
    }

    return {
        props: {
            restaurants,
        },
    };
}

pages/[id].js

// Return a list of possible value for id
export async function getStaticPaths() {
    const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants`);
    const restaurants = await res.json();

    let paths = restaurants.map(({ id }) => {
        return {
            params: {
                id: id.toString(),
            },
        };
    });
    return { paths, fallback: false };
}

// Fetch necessary data for the restaurant details using params.id
export async function getStaticProps({ params }) {
    const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants/${params.id}`);
    const restaurantData = await res.json();

    return {
        props: {
            restaurantData,
        },
    };
}

Describe the bug

I have built an application with NextJS that has an internal API and I use the getStaticProps methods to query the API.

You can find the deployed app here: https://tailor-challenge.vercel.app/

And also the github repository here: enter link description here

The application works perfectly in development mode and the deploy I made in Vercel also works. But when I run the next build mand I get the following error:

Build error occurred
FetchError: request to http://localhost:3000/api/restaurants failed, reason: connect ECONNREFUSED 127.0.0.1:3000
    at ClientRequest.<anonymous> (/home/silinde87/Jobs/tailor/TailorChallenge/node_modules/node-fetch/lib/index.js:1461:11)
    at ClientRequest.emit (node:events:376:20)
    at Socket.socketErrorListener (node:_http_client:474:9)
    at Socket.emit (node:events:376:20)
    at emitErrorNT (node:internal/streams/destroy:188:8)
    at emitErrorCloseNT (node:internal/streams/destroy:153:3)
    at processTicksAndRejections (node:internal/process/task_queues:80:21) {
  type: 'system',
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED'
}
info  - Collecting page data .npm ERR! code 1
npm ERR! path /home/silinde87/Jobs/tailor/TailorChallenge
npm ERR! mand failed
npm ERR! mand sh -c next build 

NextJS internal API

/api/restaurants/index.js

export default function handler(req, res) {
    const { method } = req;
    
    switch (method) {
        case 'GET':
            getRestaurants();
            break;
        default:
            res.status(405).end(`Method ${req.method} Not Allowed`);
    }

    function getRestaurants() {
        const restaurants = data;
        res.status(200).json(restaurants);
    }
}

/api/restaurants/[id].js

export default function handler(req, res) {
    const { id } = req.query;
    const { method } = req;

    switch (method) {
        case 'GET':
            getRestaurantById();
            break;
        default:
            res.status(405).end(`Method ${req.method} Not Allowed`);
    }

    function getRestaurantById() {
        const restaurants = data.find((el) => el.id.toString() === id.toString());
        if (restaurants) res.status(200).json(restaurants);
        else res.status(405).end(`There is no Restaurant with id: ${id}`);
    }
}

Pages from NextJS

pages/index.js <-- Where I fetch the restaurants list

export async function getStaticProps() {
    const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants`);
    const restaurants = await res.json();

    if (!restaurants) {
        return {
            notFound: true,
        };
    }

    return {
        props: {
            restaurants,
        },
    };
}

pages/[id].js

// Return a list of possible value for id
export async function getStaticPaths() {
    const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants`);
    const restaurants = await res.json();

    let paths = restaurants.map(({ id }) => {
        return {
            params: {
                id: id.toString(),
            },
        };
    });
    return { paths, fallback: false };
}

// Fetch necessary data for the restaurant details using params.id
export async function getStaticProps({ params }) {
    const res = await fetch(`${process.env.NEXT_PUBLIC_NEXTAUTH_URL}/api/restaurants/${params.id}`);
    const restaurantData = await res.json();

    return {
        props: {
            restaurantData,
        },
    };
}
Share Improve this question asked Jun 27, 2021 at 17:34 Silinde87Silinde87 411 silver badge2 bronze badges 1
  • Does this answer your question: nextjs error when build production for static website? – juliomalves Commented Jul 6, 2021 at 23:51
Add a ment  | 

1 Answer 1

Reset to default 6

I took this quote from the official documentation, link below:

Note: You should not use fetch() to call an API route in >getStaticProps. Instead, directly import the logic used inside >your API route. You may need to slightly refactor your code for >this approach.

Fetching from an external API is fine!

https://nextjs/docs/basic-features/data-fetching

Basically because the code inside getStaticProps or getStaticPaths is never executed in the browser, so you can safely call the data source directly there.

Also the failure happens because the app is not running when building, so the localhost api is not available. You can confirm this by running the app via ’yarn dev’ or ’npm run dev’ in another terminal window, and building the app in another terminal window. This way it should build just fine, but it's not remended way of doing it. I would refactor the code so that there is no fetch to the api of this app in those getStaticProps and getStaticPaths functions.

Same goes for getServerSideProps, that is also just run on the server, so you shouldn't be doing fetches to the api there either. Only the browser should do fetches to the api, for example if you want the user to be able to post some data to the app.

本文标签: