How to build a website using Gatsby & Airtable in 30 mins
Tags: gatsby, airtable, graphql, react
Published: 2020-05-18 14:55:05

We all love Airtable for various reasons and use cases. In these times of COVID, we have seen many websites built using Airtable to solve different issues. Popular ones include [candor.co](https://candor.co/hiring-freezes), etc..

Airtable has a killer feature ["share view"](https://support.airtable.com/hc/en-us/articles/205752117-Creating-a-base-share-link-or-a-view-share-link), where you can share the view of your table and embed it on your website using a simple iframe. I have also used the same feature for building the first version of [Startups vs COVID](https://www.startupsvscovid.com) - a live repository of funds, support & resources for startups tackling COVID-19.

A simple HTML website with the Airtable iframes which looked like this:

![First version of website](https://dev-to-uploads.s3.amazonaws.com/i/j6hwtk8woacvc41kawtj.JPG)

But here are some of the drawbacks of this version:

- No way to share/highlight individual records
- Lack of SEO
- Unable to track analytics of each record
- Unable to share individual records on social

To solve this problem, a second version of the platform was built using Gatsby and Airtable without any iframes.

And here is the second/current version:

![Modified version of website](https://dev-to-uploads.s3.amazonaws.com/i/muy94p38znm0ks65kyr3.JPG)

####Why Gatsby?
* Love for React

* Previously built [Leapcode](http://leapcode.io/) using React and [nextjs](https://nextjs.org) and my [personal website](http://sethusathyan.in/) using Gatsby.

* Automatic static pages generator

* Blazing fast website 
* Faster deployment using Netlify
* PWA and faster page load

* Plugin library

####How to build the website using GatsbyJs & Airtable?

>In this article, we'll focus only on connecting airtable & displaying data on your gatsby web page. We are not going deeper into the design of the website here.

First, install GatsbyJS and start a project. [Here](https://www.gatsbyjs.org/tutorial/) is how you can do it. You can also use one of the [starter packs](https://www.gatsbyjs.org/starters/?v=2) to get started.

Gatsby has several plugins that will help you integrate with different apps. Here we are going to take advantage of the *gatsby-source-airtable* plugin; it sources data into the website from the Airtable base. It is a prewritten module that uses airtable API to convert to Gatsby GraphQL.

Once your Gatsby website & the Airtable base is ready, install the `gatsby-source-airtable` plugin in your folder.

```
# using npm
npm install --save gatsby-source-airtable

# using yarn
yarn add gatsby-source-airtable
```
#### Get Started

Here is how the folder will look once you finish building:

![Folder structure](https://dev-to-uploads.s3.amazonaws.com/i/a5rkpb25f5nv5tjnuv0g.png)
**Integrating Airtable to your code**

Once you have installed `gatsby-source-airtable` plugin, configure your Airtable tables in the `gatsby-config.js` file as shown below:

```javascript
{
	resolve: "gatsby-source-airtable",
      options: {
        apiKey: process.env.AIRTABLE_API_KEY,
        tables: [
          {
            baseId: "YOUR_AIRTABLE_BASE_ID",
            tableName: "YOUR_TABLE_NAME",
          },
				]
			}
}
```
- Airtable API key - This can be found in the Airtable on Help→API Documentation. You should inject your API key using an environment variable instead of using it directly in the file.
- The base ID of your base can be found in the API Documentation.

In this article, we are using only one table. You can add as many tables you want and should specify that inside the tables in `gatsby-config.js`

#### Getting data from Airtable to our Gatsby Project

Gatsby uses GraphQL to send data to different pages. The plugin `gatsby-source-airtable` will convert Airtable's REST APIs to GraphQL schemas.

Let's start by checking if you are getting data from the Airtable API using the GraphQL interface Gatsby has.

Start your gatsby server:

```
gatsby develop
```
Go to your: `http://localhost:5000/_graphql`

Now, let's run a simple query to check the data from the Airtable. `gatsby-source-airtable` provides a query called `allAirtable`, which will fetch all the data.
```javascript
query {
	allAirtable {
		edges {
			node {
				column_name_1
				column_name_2
			}
		}
	}
}
```
At this point, we have got the airtable connected, and the data should be coming to the GraphQL. Next step is to bring this data to our homepage which is `pages/index.js`
```javascript
import React from "react"
import { graphql } from "gatsby"

export default ({data}) => {

    const allAirtableData = data.allAirtable.nodes;
    return (
        <div>
            {
                allAirtableData.map((node) => (
                    <div>
                        <img src={node.data.column_name_1} />
                        <h1>{node.data.column_name_2}</h1>
                        <a href={`/${node.recordId}`}>Click Here</a>
                    </div>
                ))
            }
        </div>
    )
}

export const query = graphql`
    query {
        allAirtable {
            node {
		   recordId
			data {
	                column_name_1
	                column_name_2
			}
            }
        }
    }
`
```
That was simple! We mapped the list from the `allAirtable` query to the `data` variable in the react component. Then we iterated the list using `map()` and listed all the data from the airtable base.

#### Creating standalone pages for each record

To improve the SEO, creating pages for each row felt like a good idea, but we didn't want to create it manually for every single row; instead, we wanted to automatically generate these pages when the Airtable updates. The best way to do this is to run the whole project on a backend server and route using the server-side rendering. But Gatsby offers an inbuilt function to create pages with gatsby builds. That was a big time saver for us. We didn't have to maintain a backend server to run our website.

Before we begin, let's start by creating a standard template for that page.

Create a new folder "template" and create a file called `post.js` inside that.

```javascript
import React from 'react'
import { graphql } from 'gatsby'

export default ({ data }) => {

    return (
    <div>
        <h1>{data.airtable.column_name_1}</h1>
        <img src={data.airtable.column_name_2} />
    </div>
    )
}

export const query = graphql`
query GetRecord($recordId: String!){
    airtable(recordId: { eq: $recordId}) {
        id
        table
        recordId
        data {
            column_name_1
            column_name_2
        }
    }
}`
```

On a quick look, the GraphQL query became a bit complex, but it's relatively easy. There is a new variable `$recordId`, which is basically the id of each row/record in the airtable; the value of `recordId` would be passed from a script (we will be doing it in the next step) and would be used to fetch the corresponding record from the airtable.

#### Introducing the createPage function

`createPage()` is an inbuilt function in gatsby to create pages on the build programmatically. Now, all we have to do is, get all the records from the airtable, iterate through each record, and create pages for each one.

To begin, we need to create a new file, `gatsby-node.js`, on the root folder with the following content.

```javascript
const path = require(`path`);
exports.createPages = ({ graphql, actions }) => {

  const { createPage } = actions
  return new Promise(async resolve => {

    const result = await graphql(`
        {
        allAirtable {
          edges {
            node {
              table
              recordId
              data {
                column_name_1
                column_name_1
              }
            }
          }
        }
      }
    `)
    // For each path, create page and choose a template.
    // values in context Object are available in that page's query
    result.data.allAirtable.edges.forEach(({ node }) => {
      createPage({
        path: `/${node.recordId}`,
        component: path.resolve(`./src/template/post.js`),
        context: {
            recordId: node.recordId,
        },
      })
    });
    resolve()
  })
}
```
Step by step process of what is happening in this page

1. Run a graphQL query with `allAirtable`. This will fetch every row from the airtable base and store it in a constant called `result`.
2. Iterate through each array inside `result.data.allAirtable.edges`, which is basically each record in the airtable base
3. `createPage()` will now generate pages with path `/:recordId`
4. It will use the component as the template for each page. Here we specified it as `post.js`, which we created before this.
5. `context` will send the `recordId` to the template which we used in the graphQL query in `post.js`

Voila! Let's do a gatsby deploy again to see individual records in a new page. You can type the URL with any `recordId` → eg: `localhost:5000/rec2312321413`

Congrats! Now you have all the data that you need from the Airtable base in your frontend. There is a lot more you can do with this, such as working with multiple tables, webhooks for Airtable, components for your frontend, PWA, etc. Stay tuned for the next article to know more about how to implement these.

Thank you so much for reading. Leave a comment if you have any questions or suggestions!