Product teams should be thinking differently about documents.Read blog post.
Anvil Logo

Environment variables at runtime in Gatsby

Author headshot
By Derek Foster

Being a static site generator, Gatsby only uses environment variables at build time. But what about using environment variables at run time? Read on for three ways to access environment variables in the browser.

Back to all articles
Environment variables at runtime in Gatsby

The entire premise of Gatsby and other JAM stack web sites is that there is no runtime environment—no server! Sites made using JAM stack architecture ‘generate’ (or build) HTML pages before a client accesses them, so there’s no need for an application to be actively running in the browser. The only client-side JS is used for data fetching and ‘hydration’, which is setting up DOM nodes with event listeners. Both of which are easily done in vanilla JS in the browser—no application runtime required.

In Gatsby-speak, you can think of it this way: Gatsby is not running in your browser1. When you run Gatsby, you are building assets that your host will serve to users via CDN. Those assets will be HTML, JS, and probably some images. Those assets are static, so Gatsby won’t be running1. Neither will React! This React method will run once to perform hydration, but that’s it. No running process for us to refer back to.

There are many cases where you need to access environment variables at run time, like data fetching from your backend (is your Gatsby site access data from production, staging, local, or some other environment?). Here are the three ways to enable run time environment variables for your Gatsby site:

  1. Use environment variables in your Gatsby-config file, fetch them in your React components from Gatsby’s data layer (via a GraphQL query).
  2. Use Gatsby’s built-in solution: prepend GATSBY_ to your environment variables.
  3. Use this plugin to allow your environment variables to be accessible at runtime.

Build time environment variables in gatsby-config

The first method to use environment variables at run time doesn’t actually use them at run time. Since environment variables are available at build time, you can use them to set values in your gatsby-config.js file and retrieve them in your pages and components.

Depending on the environment you build your site in, you will get statically generated pages that use the values of the environment variables you want. Sure, you’re not actually using environment variables at run time, but the effect is the same: different values for your website based on the environment. Was that a confusing sentence? Probably. Let’s see an example:

// gatsby config.js

const dotenv = require('dotenv')

  path: `.env.${process.env.NODE_ENV}`,

module.exports = {
  siteMetadata: {
    siteName: 'Anvil',
    envVarAtBuildTime: process.env.YOUR_ENV_VAR,
    title: 'Anvil - Paperwork that makes the data work',
      'APIs and no-code form builder for collecting data, not PDFs. Webform meets PDFs and e-sign.',

Set the YOUR_ENV_VAR variable in your gatsby config, like this

// in a page component (src/your-page.js)
import React from 'react'
import { graphql } from 'gatsby'

export default function MyPage({ data }) {
  return (
      Your environment variable value is:{' '}

export const pageQuery = graphql`
  query {
    site {
      siteMetadata {

Use the value from YOUR_ENV_VAR by querying for it via envVarAtBuildTime. You can use the value however you want within your React components.

The down side to this method is that you must get these values within a React component on your site because the only way to query Gatsby’s data layer is via a page query or a static query, both of which require a React component. You can pass down the value as a prop, so you are still able to use the value in any component or Layout you’d like.

GATSBY_ environment variables

The creators of Gatsby built in a solution to use environment variables at run time. Any environment variables prefixed with GATSBY_ will be available in the browser for you to use.

This method is the simplest of the three to get environment variables at run time, but I’m not a fan of this one. Environment variables are used for multiple applications, so prefixing with GATSBY_ is confusing for other projects that use the value. It also connotes something different overall. For example, APP_URL and GATSBY_APP_URL will have the same value, but developers will understand them differently.

Webpack: Gatsby plugin for environment variables

Under the hood, Gatsby uses webpack to build production-ready bundles for the browser. This plugin updates the webpack config Gatsby uses to build your site by adding your environment variables to the bundle as global variables with the same identifier. Using the example from the last section (APP_URL), this plugin would inject your environment variable as process.env.APP_URL.

If webpack is out of your understanding right now—no worries!2 That’s the point of Gatsby and its plugin system, you don’t need to fuss about the internals of these things. This plugin is my favored approach for using environment variables in Gatsby because it’s easy to configure and keeps your code base framework-agnostic. Compared to the previous 2 methods, you reference environment variables as you would with any other JavaScript project: process.env.YOUR_ENV_VAR_HERE.

Here’s how to configure the plugin:

  1. yarn add -D gatsby-plugin-env-variables
  2. Edit your gatsby-config.js file like below. It uses the environment variables APP_URL and ANVIL_API_KEY as examples.
    // gatsby-config.js
    module.exports = {
        plugins: [
                resolve: 'gatsby-plugin-env-variables',
                options: {
                    allowList: ["APP_URL", "ANVIL_API_KEY"]
    Using Gatsby plugin to inject APP_URL and ANVIL_API_KEY into your bundle (able to use these as process.env.APP_URL and process.env.ANVIL_API_KEY) within your code


With the rise of Jamstack architecture for content sites, run time environments have left the browser. Even with no run time environment, we still need to access environment variables for setting up staging and test environments, using public API keys to fetch data, and keeping our codebase change-resistant if values (like domains and URL paths) change.

The three methods mentioned in this blog post don’t actually expose run time environment variables for you to use (remember, there is no running application in the browser! Just static assets and React hydration), but provide you with the functionality to use those values where you need them. Each method has its pros and cons, so make sure you choose the right method for you. If you’d like to discuss your use case and which method is right for you, we’d love to hear from you at Happy Gatsby-ing!

  1. Gatsby (+ other JAM stack frameworks) have grown to include features like SSR. While these features enable dynamic functionality like user-specific pages, the assets are still static and the JavaScript used to execute this functionality is fired on event listeners to Gatsby's specific servers to only render HTML. Serverless functions are a good use case here, since we don't need a running server to render HTML and send it to the browser... but either way, still no dedicated runtime environment for Gatsby or React, unfortunately.
  2. If you are familiar with webpack, this plugin uses the DefinePlugin under the hood with Gatsby’s node APIs to define the variable in your bundle

Sign up for a live demo

Request a 30-minute live demo today and we'll get in touch shortly. During the meeting our Sales team will help you find the right solution, including:
  • Simplifying data gathering
  • Streamlining document preparation
  • Requesting e-signatures
  • Building and scaling your business
Want to try Anvil first?Sign up for free
Want to try Anvil first?Sign up for free