Humbledev logo

humbledev

Building a Next.js static website based on Airtable

09.05.20202 Min Read — In Next.js

The Next.js team is continuously delivering killer features. The getStaticProps function is one of them (available from Next.js 9.3). It is only run at build time, contrary to getInitialProps who is run on both server runtime and client-side runtime. Its purpose is to compute the necessary data for your page to render ahead of time (i.e. before a client even requests your page). This has several perks:

  • Only compute the data once, at build time, when you run next build. You only need to call APIs/read from databases once. This means you can afford to do slow stuff as well as not save some money if you're paying for APIs
  • Page can be statically served from a CDN, no need for a traditional backend. This is huge!
  • Better performance client-wise since data doesn’t have to be computed on each request, you can directly serve the fully rendered page to the user. This is huge as well!

What is beautiful about the getStaticProps function is that you can rely on server-side stuff like reading from a database, a CMS or from the filesystem, and the code as well as dependencies used to do this will automagically be removed from your client bundle. Gatsby, on the other hand, makes you write the fetching logic in the gatsby-node.js file. Next.js provides in comparison a per page approach, which I think is more intuitive. You can, of course, build hybrid pages where part of data is fetched at build time, and the rest of the data is fetched client-side for dynamic stuff that depends on user input for example.

To demonstrate this, we’ll build a small app that displays data from Airtable. If you don't know Airtable, it's kind of an Excel/Database hybrid service that enables a team to make nice spreadsheets containing complex information easily. The data can then be queried with an API. Airtable provides premade templates for showcasing or quick starting a project. We’ll use the Product catalog one. It looks like this:

Airtable product catalog template
Airtable Product catalog template

The goal of our app is to allow non-technical people to edit an online spreadsheet and allow other people to view the spreadsheet data on a website. Airtable is a pretty cool product. It’s excellent for rapid prototyping and will provide a simple database that you can edit easily. The UI is stellar and their free tier is pretty generous too.

Airtable has a Node.js lib we can use to make requests to the Airtable API easily instead of making HTTP requests by hand.

As you can see, it already includes a nice base to work on such as images, categories, prices...

Let's build a page to display basic furniture information: the name of the furniture, its type, some images, and its price. As said earlier, we’ll need to query the Airtable furniture catalog in a getStaticProps function. Let’s put in our main page file. /pages/index.js. Simply export an async function named getStaticProps:

import React from 'react';

export async function getStaticProps() {}

function Home() {
  return 'Hello';
}

export default Home;

getStaticProps will feed the data it returns to the default React component Home. Let’s say Home needs a list of products, then that’s what we will return from getStaticProps:

export async function getStaticProps() {
  const products = [];

  return {
    props: {
      products,
    },
  };
}

function Home({ products }) {
  return 'Hello';
}

To fetch the products, we’ll use the convenient airtable npm package which will call the Airtable API under the hood. Key things here:

  • We need to provide an apiKey parameter. You’ll get this from your Airtable account.
  • We need to provide a base ID. It is a unique identifier for your Airtable spreadsheet (here named Product catalog)
  • Lastly, we need to provide the name of the table we want to query, here Furniture
  • We select just the fields we need Name, Type, Images and Unit cost
import Airtable from 'airtable';

export async function getStaticProps() {
  const airtable = new Airtable({
    apiKey: 'YOUR_API_KEY',
  });

  const records = await airtable
    .base('YOUR_BASE_ID')('Furniture')
    .select({
      fields: ['Name', 'Type', 'Images', 'Unit cost'],
    })
    .all();

  const products = records.map((product) => {
    return {
      name: product.get('Name'),
      type: product.get('Type'),
      images: product.get('Images').map((image) => image.url),
      cost: product.get('Unit cost'),
    };
  });

  return {
    props: {
      products,
    },
  };
}

That’s it. This function will be executed at build time and provide the products prop to the page component Home. We can now simply display it by creating a quick Product component. Styles are inlined for brevity.

function Product({ name, type, images, cost }) {
  return (
    <div style={{ padding: '32px' }}>
      <div>
        <b>{name}</b>
      </div>
      <div>{type}</div>
      {images.map((image) => (
        <img style={{ maxWidth: 200 }} key={image} src={image} alt={name} />
      ))}
      <div>${cost}</div>
    </div>
  );
}

function Home({ products }) {
  return (
    <div>
      <h1 className="title">Airtable Next.js example</h1>

      <div>
        {products.map((product) => (
          <Product
            key={product.name}
            name={product.name}
            type={product.type}
            images={product.images}
            cost={product.cost}
          />
        ))}
      </div>
    </div>
  );
}

This will look like this:

Airtable Next.js example
Our Airtable furniture catalog displayed by our Next.js app

I hope you found this (humble 😀) post useful. If you have any question, leave a comment below or ping @windkomo on twitter 😄

You can find the full GitHub repo here.

PreviousCreating a nice loading button with React Hooks
Subscribe to the newsletter
Unsubscribe at any time