Guides & Tutorials

How to make a fetch request using node-fetch v3

I’ve been playing around with Astro lately by building a Photography based portfolio site using Pexel’s API. During the process, I ran into an issue with getting my fetch request to work within my Netlify Serverless Functions. Upon further review, I made the discovery that node-fetch v3 had a breaking change that was causing it not to work with my current setup. This post will break down the initial issue I had with node-fetch as well as what will need to be done to resolve it when adding node-fetch within Netlify Functions.

Note: This is not an Astro-related issue, I just so happened to be working on a site using Astro when I ran into this error. This issue is specific to the new node-fetch version when using it within Netlify Functions.

node-fetch v3 vs. v2

Let’s say you are in the process of working on a new site that requires you to pull data from an external API. You’ve installed node-fetch and you’ve already created your Netlify Function that contains your fetch request and it looks something like this:

const fetch = require('node-fetch')

export const handler = async () => {

  const baseUrl = '<https://api.pexels.com/v1/collections/gb7kvpf>'

  const response = await fetch(baseUrl, {

    method: 'GET',

    headers: {

    Authorization: `${process.env.PEXELS_API_TOKEN}`

  }

})

.then((res) => res.json())

.catch((err) => console.error(err))

...

When running ntl dev or netlify dev you will immediately get the error below in your console:

"errorMessage":"Cannot use import statement outside a module","errorType":"SyntaxError","level":"error","stackTrace":["ort fetch from 'node-fetch';","^^^","","taxError: Cannot use import statement outside a module","compileFunction (<anonymous>)"

This error message is letting us know that we are unable to use the require() syntax since it only works with CommonJS. Node-fetch v3 was updated to an ESM-only module which now makes it so that instead of using require(), you will now need to use imports.

Now that we know why it wasn’t working as expected, we can replace require with an import like the snippet below.

- const fetch = require('node-fetch') 
+ import fetch from 'node-fetch';

Note: As of 08/22 node-fetch v2 is still compatible with CommonJS and will get the same bug fix updates as V3. If you decide you would rather stick with v2, you will just need to install it using npm install node-fetch@2 https://www.npmjs.com/package/node-fetch

Update your netlify.toml

Now that you’ve updated your import, you will need to go into your netlify.toml file and add the below snippet:

  [functions]
    node_bundler = "esbuild"

This tells Netlify that you will be using ESM for this site. Once you’ve saved your changes and re-uploaded your dev server, you should see that your fetch request is now going through.

Or… update your package.json

Another option that is available is that instead of updating the TOML file, you can go into your package.json and above the scripts object you will need to add "type": "module".

  "type": "module",
  "scripts": {
    "dev": "astro dev",
    "start": "astro dev",
    "build": "astro build",
    "preview": "astro preview"
  },

This update will work the same as adding the node_bundler to your TOML file. You will also need to make sure to close out of your current server and re-run it again to see the changes that were made.

Done!

Now that you’ve made the necessary updates to resolve the node-fetch issue on your project, you can now focus on crossing the finish line. If you want to check out the node-fetch solution on the site I made with Astro and the Pexels API, you can check it out here.

Keep reading

Recent posts

How do the best dev and marketing teams work together?