Next.js server side api call returns 500 internal server error

16,485

No, the server setup is not necessary.

This is happening because the browser/client is not capable of resolving your docker container's hostname. As it stands, the only solution I know of is to check for the req object in getInitialProps (so as to determine which environment the fetch will run in) and call the Docker hostname when on server, localhost when on client. E.g.

async getInitialProps (ctx) {
    if (ctx.req) // ctx.req exists server-side only
    {
        // call docker-host:port
    }
    else {
        // call localhost:port
    }
}
Share:
16,485
DanV
Author by

DanV

Updated on July 02, 2022

Comments

  • DanV
    DanV almost 2 years

    I'm finally dipping my toe into the world of server side react using Next.js, however I'm pretty stumped with this issue.

    I'm making a call to an API from pages/customer-preferences.tsx using isomorphic-unfetch

    CustomerPreferencesPage.getInitialProps = async () => {
      const res = await fetch(API_URL + '/preference-customer');
      const initialData = await res.json();
      return { initialData };
    };
    

    All works fine locally in dev mode or once built and ran build > start. To host it I'm running it from a docker container node:10, and when I run this locally all is fine also. The issue only happens once it's deployed.

    When I navigate to / and then click a link to /customer-preferences all works as expected. But if I refresh the page or load the page directly at /customer-preferences I see this error from Next.js

    enter image description here

    So the issue only seems to happen when trying to make the API calls from the server and not the client.

    I've also setup a simple express server to use instead, but not sure if this is necessary?!

    const express = require('express');
    const next = require('next');
    
    const port = parseInt(process.env.PORT, 10) || 3000;
    const dev = process.env.NODE_ENV !== 'production';
    const app = next({ dev });
    const handle = app.getRequestHandler();
    
    app.prepare().then(() => {
      const server = express();
    
      server.all('*', (req, res) => {
        return handle(req, res);
      });
    
      server.listen(port, err => {
        if (err) throw err;
        console.log(`> Ready on http://localhost:${port}`);
      });
    });
    

    When checking the server logs I get this:

    FetchError: request to http://xxx failed, reason: getaddrinfo EAI_AGAIN xxx xxx:80
    

    Any help would be greatly appreciated.

  • DanV
    DanV over 4 years
    I'm making a call to an API from pages/customer-preferences.tsx using isomorphic-unfetch
  • struensee
    struensee almost 4 years
    @cr05s19xx Not quite. Isomorphism is the culprit here, but this has nothing to do with the module import. The issue is that getInitialProps is isomorphic and therefore calls the Docker hostname on the client AND the server. The hostname is exposed as localhost on the client-side.