We use Airtable a lot internally: project management, event organization, marketing initiatives, content calendars, the works. We’ve started dabbling with the Base APIs directly for use-cases where we wanted to show certain data to end users without needing to duplicate information in our project workflow to a separate CMS. Our language landing pages, for example, are all generated from our base where we keep track of each language’s progress.
So, we’ve got what’s essentially a database with a fancy interface built in. Adding ZEIT’s Now and Next.js make it trivial to build applications that interact with that database’s API…the only thing left to do is wire them all together to build our own personal video CMS.
We want to build a small application that allows us to have a (relatively) pretty interface around showing off our videos to friends along with a little metadata, like a title and description. We also want to be able to upload new content, then handle the webhooks coming back from Mux so we can keep each video’s status in our Airtable base up to date without doing anything manually.
Let’s take a look at what the final experience will be for folks looking at our fantastic video content:
And the interface for adding new content:
If you want to see it yourself, the deployed version you see in the videos is live.
Clone the example repo and mosey on into the newly cloned directory. Once we’re there we’ll install all the npm dependencies we need, then copy the
.env.example file so we can start copying over our own configuration values.
Set up your Airtable base
First we need to have a table for our videos in a base. For things to work out of the box you’ll need the table to have exactly the fields from the template at a minimum, but additional fields/tables won’t affect anything.
Now you need to go grab your Airtable API key and base ID for your newly created store. The Airtable documentation is any easy place to start.
Update the values in
AIRTABLE_BASE to match.
Grab a Mux Asset token
Go generate a new Mux Asset Token and update the
MUX_TOKEN_SECRET values in
.env to what’s in downloaded .env file.
Set a password
We’ll use a simple basic auth strategy to keep anyone else from uploading videos. Set
MANAGEMENT_PASSWORD to something only you’ll be able to guess. When you go to use the UI, you only need to specify that password in either the username or password field.
Make sure your Now CLI is configured
Decide on an alias, then set up a webhook in Mux
The last thing we want to do before deploying is update the alias/name for our new CMS in
now.json, then go add that alias to Mux. This makes sure the webhook notifications for your created (or modified) assets are delivered to the right place when the time comes.
Everything should be set up and ready to go!
deploy command will export all the values in our
.env file, then run
now to deploy everything to ZEIT Now and alias that new deployment to whatever you set the alias to be.
Optional: If you want to run the UI locally, add the URL provided from the step above to your
.env file as
We used Now Lambdas with the @now/node builder to create our API endpoints that interact with the Airtable and Mux APIs. Our Next.js client will then hit these endpoints when creating our CMS’s interface. The lambdas to get and list videos use our basic Airtable wrapper to (you guessed it) get a single video or list all of them from the base. If you’ve used the Airtable API before, nothing in there should be too surprising.
Creating a video is where things start to get a little interesting. Because we want to use direct uploads and push content directly from our interface, we create our new asset in our app first, then use the
passthrough field to include that local ID in any WebHook notifications we receive. Here’s what our video creation endpoint looks like:
You can do this other ways, but this pattern is nice because it allows us to start with an object that lives in our world, then reference that in everything else we do. This is particularly helpful in the direct uploads world, since the initial ID that Mux returns is for a newly created upload object, which may or may not grow up to become an asset one day. If the client does upload a file and that file’s valid, suddenly we’re getting new webhook notifications for assets and we can use that nifty passthrough field to look it up without having to know anything else about the asset from a Mux perspective.
Let’s take a look at how we handle the webhooks:
Some things you may want to make note of here:
The UI code is intentionally simple. For the most part a page uses
getInitialProps to go fetch data from the API, whether it’s server-side rendered or not. One gotcha here is that if you use something like isomorphic-unfetch, like we did, you’ll need to make sure to use the fully-qualified URL. To get around this, we made a simple helper that checks to see if we’re being rendered on the server or not. If we are, we use the full host (
req.headers.host), otherwise we can just use relative paths.
Player component we’re just using a simple HTML5 player with HLS.js installed. The component only needs a
playbackId passed in as a prop and it handles setting up the playback URL and a default poster.
Thumbnail component is similar, but it uses the provided
playbackId to be able to create our nice list of videos in the index. When hovered, it swaps out the image source from
We only worry about the fields we know about for the UI, so a fun tidbit is you can otherwise use the Airtable base however you’d like! Add additional tags, have it work through a review process, create other tables in the base, etc, nothing outside of the main column names will affect this functionality.
This example application actually works really well for truly personal videos, but Airtable’s rate limits would be problematic if one of your videos went viral. To get around this, you could add the
exportPathMap function to your next.config.js file. In that function you’d be able to request each video and create a static route for that asset, then generate static HTML so you only need to hit Airtable to create new assets.
We’re always looking for helpful, fun things to build to show off Mux 💅. If there’s something specific you want to see, drop us a line!