On a recent project I’ve been experimenting with adding Airtable as a content management system for Eleventy (11ty). Below I document the notes around how I’ve got a simple set up running…
Because tech posts tend to date, I’m using the following npm packages… there may be modifications needed for newer (or older) releases!
I’m going to make some assumptions- firstly that you know how to use Airtable, and you have a basic table set up already. And secondly you know the basics of 11ty.
To summerise what we’re aiming for… when 11ty generated the site it will pull data in from a table view within Airtable, and then use that to populate a page or create a set of pages, and we’re going to make sure that it is cached for a day for local development.
An early commit of this work can be found in Github, and the resulting Airtable powered page is the Kingdom Code Jobs board.
Because we’re setting a cache, and we’re going to need an environment file to store the Airtable API key we want to make sure that we’re never going to commit these things to the git repo. In your .gitignore
file add the following:
.cache
.env
The three packages we’re using here are:
npm install @11ty/eleventy-cache-assets airtable dotenv
From Airtable you’re going to need the following things:
The API key should get placed into a new .env
file in the root folder. We don’t want that in our git repo though- so make sure it is in your .gitignore
:
AIRTABLE_API = "API KEY FROM AIRTABLE"
You can export data from a JavaScript file to add data, too. This allows you to execute arbitrary code to fetch data at build time. [1]
This means that we can do an API call to Airtable as the site builds - and the data that is returned is automagically exposed to our templates.
Example code is in the gist below, but in summary what we’re doing here is:
new AssetCache(assetCacheId);
if (asset.isCacheValid("1d"))
base(airtableTable).select({…
. We could do a lot of filtering of the data in JavaScript, but I prefer to keep this in Airtable so it is possible for a non-technical editor to see what is going to be published.asset.save(allDatasets, "json");
before resolving the JS promise with the data.At this stage you can make a test with your new data. With 11ty anything within the data
folder is exposed in the global data structure with the file name as the key in the data object. So if you’ve named your data file airtableData.js
, you’re able to access in your views with {{ airtableData }}
.
This means that in a new view you’ll be able to have the following to test your view:
{% if airtableData.length %}
{% for item in airtableData %}
{{ item | dump }}
{% endfor %}
{% else %}
<p>No data pulled from Airtable</p>
{% endif %}
When you trigger an 11ty build the first time round 11ty will pull the data from Airtable, store the returned JSON in the .cache
folder, and then deliver it to the template for you to use as any other data in 11ty.
I’m hosting most of my 11ty projects with Netlify which has the deploys triggered by commit. By pulling the data out of the deploy push to deploy doesn’t work… so it would be nice to be able to trigger the deploy from Airtable.
Helpfully, Netlify gives you a ‘Build Hook’ URL, even on the free plan. You can read all about build hooks on the Netlify Documentation, however the summary is that you submit a POST
to the unique URL, and a deploy is triggered.
Airtable allows you build custom ‘apps’ in each table, which can be hooked up to run some JavaScript… so three lines of JS later and you have a very simple deploy button within Airtable:
const deployHook = "https://api.netlify.com/build_hooks/[[ YOUR HOOK ID ]]";
output.markdown(`Deploying to **Netlify**.`);
const request = await fetch(deployHook, {method: 'POST'});
Very simple… there’s lots of areas where this can be improved on, but it’s simple enough to do the job.
Reference from 11ty Documentation: JavaScript Data Files ↩︎