Next.js throws malformed URL error when importing Airtable library in getServerSideProps

I’m working on a Next.js project and trying to fetch data from Airtable inside the getServerSideProps function. However, I keep getting this weird error about malformed URLs even though I’m not using any relative URLs.

My setup:

pages/dataPage.js

import React from 'react';
import AirtableLib from 'airtable';

export const config = {
  runtime: 'experimental-edge',
};

export async function getServerSideProps(context) {
  AirtableLib.configure({
      endpointUrl: 'https://api.airtable.com',
      apiKey: process.env.AIRTABLE_KEY,
  })
  const database = AirtableLib.base(process.env.AIRTABLE_DATABASE);
  const records = database('myTable').select({...});
  return { props: { data: [] } };
}

class DataPage extends React.Component {
  render() {
    return (<div>Content here</div>);
  }
}
export default DataPage;

The error I get:

Error: URL is malformed "". Please use only absolute URLs

This happens when I run npm run dev. The error disappears completely when I remove the Airtable import and related code.

I tried moving the configuration outside of getServerSideProps but that didn’t help. I also made sure to set the endpoint URL explicitly but the problem persists.

What’s really strange is that just importing the Airtable library causes this issue, even without calling any functions. It seems like this might be connected to the experimental edge runtime I’m using.

Has anyone encountered this before? How can I successfully use Airtable with Next.js server-side rendering?

Package versions:

"airtable": "^0.11.6"
"next": "^13.1.1" 
"react": "^18.2.0"

Hit this exact issue last month. Yeah, the edge runtime breaks it, but switching back to nodejs doesn’t always fix it either.

Next.js’s bundler gets confused by how Airtable constructs URLs internally. Even with nodejs runtime, the module resolution can still mess up.

Here’s what actually worked - move your Airtable setup to a separate file and use dynamic imports:

// lib/airtable.js
const AirtableLib = require('airtable');

export function getAirtableBase() {
  AirtableLib.configure({
    endpointUrl: 'https://api.airtable.com',
    apiKey: process.env.AIRTABLE_KEY,
  });
  return AirtableLib.base(process.env.AIRTABLE_DATABASE);
}

Then in your page:

export async function getServerSideProps(context) {
  const { getAirtableBase } = await import('../lib/airtable');
  const database = getAirtableBase();
  // rest of your code
}

This keeps the library separate so the bundler doesn’t try to process it upfront. Just make sure you remove the edge runtime config first - stick with default nodejs for this to work.

Edge runtime is your problem. Hit this exact issue 6 months ago trying to use Node.js libraries with edge runtime.

Airtable’s library needs a full Node.js environment, but edge runtime is stripped down and missing APIs the Airtable SDK needs.

Two options that work:

Option 1: Switch back to Node.js runtime
Remove that config export or change it to:

export const config = {
  runtime: 'nodejs',
};

Option 2: Ditch the Airtable library, use fetch
This is what I did to keep edge runtime’s performance benefits:

export async function getServerSideProps(context) {
  const response = await fetch(`https://api.airtable.com/v0/${process.env.AIRTABLE_DATABASE}/myTable`, {
    headers: {
      'Authorization': `Bearer ${process.env.AIRTABLE_KEY}`
    }
  });
  const data = await response.json();
  return { props: { data: data.records || [] } };
}

I went with option 2 - direct API calls are faster and you skip the extra library weight. Airtable’s REST API is pretty easy to work with.