Next.js - Error: only absolute urls are supported

Similar to the @Shanker's answer, but if you prefer not to install the additional package for this, here is how to do it.

async getInitialProps({ req }) {
    const protocol = req.headers['x-forwarded-proto'] || 'http'
    const baseUrl = req ? `${protocol}://${req.headers.host}` : ''

    const res = await fetch(baseUrl + '/api/products')
}

As the error states, you will have to use an absolute URL for the fetch you're making. I'm assuming it has something to do with the different environments (client & server) on which your code can be executed. Relative URLs are just not explicit & reliable enough in this case.

One way to solve this would be to just hardcode the server address into your fetch request, another to set up a config module that reacts to your environment:

/config/index.js

const dev = process.env.NODE_ENV !== 'production';

export const server = dev ? 'http://localhost:3000' : 'https://your_deployment.server.com';

products.js

import { server } from '../config';

// ...

Products.getInitialProps = async function() {

  const res = await fetch(`${server}/api/products`)
  const data = await res.json()

  console.log(data)
  console.log(`Showed data fetched. Count ${data.length}`)

  return {
    products: data
  }
}

You could utilize environment variables if your project is hosted on a provider that supports it.

env.local

// Local
URL="http://localhost:3000"

// Production
URL="https://prod.com"

Then you can use the following.

const { URL } = process.env;
const data = await fetcher(URL + '/api');

It sounds silly but worth mentioning. If you're using SSR in your webapp the fetch call will work with a relative link on the client but will fail on the server. Only the server needs an absolute link!

If you want to prevent the server from making the request just wrap it in logic

if(global.window){
   const req = fetch('/api/test');
   ...
}