Bridgetown and Environment Variables

rodreegez

Adam Rogers

Posted on December 7, 2020

Bridgetown and Environment Variables

This afternoon I had a bit of a time getting environment variables working in my first real stab at a Bridgetown site. I'm not sure I've figured out the best way to do this, but here's what I came up with.

Background

It's worth pointing out a few related background details:

  • I am a curmudgeon and I do not like change, so I switched the templating in my site to erb, which I believe is a relatively new feature of Bridgetown, but a relatively old feature of Rails.
  • I want to be able to set env vars locally, keep them out of my git repo, and set different ones in production in whatever way is apropriate for whatever production is.
  • I don't want my application code to care about what environment it's running in.

dotenv

I usually make Rails applications, and with Rails applications I usually use dotenv. This allows me to have a .env file that gets loaded when my Rails app boots. In Rails-land, we can use dotenv-rails which will hook into the application boot process and bootstrap our environment variables for us. This mostly works fine, but you can mess with it if you need to. Yay for Rails, I guess.

Bridgetown is not Rails

How, then, to hook the loading of env vars into the build process? After a bit of messing about and a nudge from the nice people on the Bridgetown discord server I discovered that one can write "plugins" for Bridgetown. Getting dotenv to play nice with bridgetown was as simple as bundle add dotenv and then creating the file /plugins/env.rb that required the gem:

# /plugins/env.rb
require 'dotenv/load'
Enter fullscreen mode Exit fullscreen mode

Setting Env Vars

With dotenv being required, any key=value pairs we put in a file called .env located at the route of the project will be loaded into the environment when Bridgetown builds.

# .env
MY_API_KEY=ABC123
SOME_OTHER_KEY=DEF246
Enter fullscreen mode Exit fullscreen mode

You're not limited to .env files, either. dotenv allows you to set key-value pairs in a whole bunch of different files, and will load each in an order of precidence.

Keeping API keys out of git

Obviously the whole point of this exercise is to keep our precious API keys out of git. To do this, I like to add .env to my .gitignore, duplicate the file and rename it to .env.example and then replace all the keys in .env.example with nonsense. I do this on basically every project so when I see a .example file I know I need to copy it to the real file, but you may want to add a reminder to your README or similar.

Pro tip: do this before you commit any of your dotenv stuff to git, else you'll have to look up how to make git forget about the original .env file and who's got time for that kind of nonsense?

Reading Env Vars

Now that we have Env Vars being set and loaded, we can read them in our views. As mentioned I'm using erb, so that should look pretty familiar to anyone who's done a little Rails:

<%# /src/_layouts/home.html.erb %>
<%= ENV['MY_API_KEY'] %>
Enter fullscreen mode Exit fullscreen mode

Why did you do this?

Static sites generally and Bridgetown particularly allow us to build "Jamstack" sites that leverage third-party APIs from the client side, and eschew a server entierly. In order to access an API though, you'll typically need to access an API key. Think Stripe API keys, Google Analytics API keys, Mapbox API keys... anything like that.

Bridgetown does have a mechanism, two in fact, for loading arbitrary key-value pairs at build time, but neither felt like a particularly suitable place to put API keys.

config.bridgetown.yml exists and you could add keys there, however this is the global config for Bridgetown, which means you would find it trickier to do the whole .example trick to keep your keys out of git, and if you did you'd have to copy your whole config across which seems like it'd be just itching to get out of sync.

You can also add keys to the site.data object in Bridgetown by creating e.g. /src/_data/env.yml. This would make our keys available through e.g. site.data.env.MY_API_KEY, but that felt like abusing a function meant for something else.

At the end of the day, I only really need to dump the right value for a given key onto the page interpolated into some JS snippit or other, and Env Vars seem like the right place to do that.

How do you load API keys into your Bridgetown site?

💖 💪 🙅 🚩
rodreegez
Adam Rogers

Posted on December 7, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Bridgetown and Environment Variables
bridgetownrb Bridgetown and Environment Variables

December 7, 2020