Last year, while working full-time as a PM, I took on a consulting project. At its core, the project wasn't too exciting: a website for a venture capital firm with about 6 static pages. But the friend who worked at the firm wanted a website that they could easily edit, and by easily, I mean even the older partners whose tech savvyness didn't extend beyond spreadsheets could edit. Initially, I suggested Squarespace or any one of the major website builders but they wanted a specific look and feel. It probably did make sense to build out a custom website.

At that time, for a while, I'd been toying around in my mind with the idea of websites backed by spreadsheets. Everyone knows how to edit a spreadsheet. A static website could totally be backed by a spreadsheet. It was the middle of 2019, and I couldn't find anything super great.

What I ended up building was a statically generated website where all the content was in Airtable. Airtable over Excel because Airtable supports image uploads. The data flowed like this:

The admin website is bare-bones: two buttons restricted by a password field. The Generate button queries Airtable for the latest content, and produces a Next.js-powered static website served at preview.domain.com. The Promote button promotes the static website from preview.domain.com to domain.com. With the staging website at preview.domain.com, you get to see if your latest updates to Airtable messed something up, and ensure everything looks as it's supposed to before going live on domain.com.

The end result was pretty satisfying. You can check out the static website here.

Change something in Airtable, click a couple of buttons, and viola! New content on the website without modifying any code or dealing with CMSes!

Multi-language support

Prior to this project, I'd never built a website with support for multiple languages. This wasn't an easy undertaking here. For one, it made the content in the Airtable tables a lot more annoying to work with.

For every language, we need to add a corresponding row to the table to represent the piece of content in that language.

Second, the live website is exported using next's static page generator, next export. Using a pretty complex exportPathMap function, each language is rendered under a separate URL with the appropriate content for that language from Airtable. So, for instance, domain.com/fr/team is the Team page in French.


Self-hosting

The admin website dynamically exports — at the touch of a button — a static next.js website. I couldn't figure out how to do this with the Vercel host. One of my favorite parts of building websites with next.js is that deployment and hosting is easy with Vercel/Now. But in this case, since I couldn't run npm run export on the Vercel host, I had to get my own Linux box. Ended up going with Linode but having to set up a server from scratch and dealing with process management, system restarts and uptime monitoring was a pain.

Stack

Here's the full-stack I used:

  • next.js - admin website + generation of static website
  • serve - static file serving
  • nginx - support HTTPS and proxy requests to serve & next.js
  • certbot - SSL certificates
  • pm2 - startup script for next and serve
  • pm2 + systemctl - managing restarts
  • CrossBrowserTesting - cross browser testing
  • Uptime Robot - uptime monitoring

Overall, there were a couple of hoops to jump through with next.js particularly for simulating dynamic routes for multi-language support, and for self-hosting. But it was worth it. Prefetch support with next.js is truly quite amazing. In the gif below, you can see that we are able to move seamlessly from page to page without browser refreshes.

No-code Websites

What I built is owned by the client. But since then, a number of similar projects have propped up.

  1. Table2Site  basically does exactly the same thing as what I built. Airtable as CMS for your website.
  2. Sheet2Site looks to be a relatively well-developed way to create an Google Sheets-backed website.
  3. Contentful is a no-frontend CMS. What the means is Contentful provides a way to store and edit content, deal with multiple languages, etc. and then, provides an API for your custom front-end to query to render the website.
  4. Glide lets you design and create mobile apps that are backed by data in Google Sheets.