Skip to content

Gatsby Environment Variables — Managing Configuration Across Environments

DodaTech Updated 2026-06-28 4 min read

Learn how to use environment variables in Gatsby for API keys, configuration, and environment-specific settings across development and production.

In this lesson, you'll understand how Gatsby handles environment variables, how to create .env files, and how to access variables in different contexts.

What You'll Learn

How to create .env.development and .env.production files, access variables in Node.js and browser code, and use variables in gatsby-config.js.

Why It Matters

Environment variables keep secrets out of your codebase. They let you use different API endpoints, analytics IDs, and feature flags across environments.

flowchart LR
    A[.env.development] --> B[gatsby-config.js]
    A --> C[Client Code]
    D[.env.production] --> B
    D --> C
    B --> E[API Endpoints]
    C --> F[Feature Flags]
    style B fill:#639,color:#fff

Setting Up Environment Variables

# .env.development
GATSBY_API_URL=http://localhost:3000/api
GATSBY_ANALYTICS_ID=UA-DEV-XXXXX
CONTENTFUL_SPACE_ID=dev_space
CONTENTFUL_ACCESS_TOKEN=dev_token
ENABLE_EXPERIMENTAL_FEATURE=true

# .env.production
GATSBY_API_URL=https://api.example.com
GATSBY_ANALYTICS_ID=UA-PROD-XXXXX
CONTENTFUL_SPACE_ID=prod_space
CONTENTFUL_ACCESS_TOKEN=prod_token
ENABLE_EXPERIMENTAL_FEATURE=false

Variables prefixed with GATSBY_ are available in browser code. Variables without the prefix are only available in Node.js (gatsby-config.js, gatsby-node.js).

Using Variables in gatsby-config.js

// gatsby-config.js
require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`
});

module.exports = {
  siteMetadata: {
    siteUrl: process.env.GATSBY_SITE_URL || 'http://localhost:8000'
  },
  plugins: [
    {
      resolve: 'gatsby-source-contentful',
      options: {
        spaceId: process.env.CONTENTFUL_SPACE_ID,
        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN
      }
    },
    {
      resolve: 'gatsby-plugin-google-analytics',
      options: {
        trackingId: process.env.GATSBY_ANALYTICS_ID
      }
    }
  ]
};

Output: The Contentful and Analytics plugins use environment-specific credentials without hardcoding secrets.

Using Variables in Client Code

Access GATSBY_ prefixed variables anywhere:

// src/components/APIStatus.js
import React, { useState, useEffect } from 'react';

export default function APIStatus() {
  const [status, setStatus] = useState('checking');

  useEffect(() => {
    fetch(`${process.env.GATSBY_API_URL}/health`)
      .then(res => res.json())
      .then(data => setStatus(data.status))
      .catch(() => setStatus('offline'));
  }, []);

  return <p>API Status: {status}</p>;
}

Output: The component fetches from the development API in dev mode and the production API in production.

Using Variables in gatsby-node.js

// gatsby-node.js
require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`
});

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;

  // Use environment variable for feature flag
  const enableBeta = process.env.ENABLE_BETA_FEATURES === 'true';

  if (enableBeta) {
    // Create beta-only pages
    createPage({
      path: '/beta/',
      component: path.resolve('./src/templates/beta.js')
    });
  }
};

Output: Beta pages are only created when ENABLE_BETA_FEATURES=true in the environment.

Adding Environment Variables to CI/CD

# .github/workflows/deploy.yml
name: Deploy
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }}
      CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }}
      GATSBY_API_URL: ${{ secrets.API_URL }}
      GATSBY_ANALYTICS_ID: ${{ secrets.ANALYTICS_ID }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm ci
      - run: npm run build
      - run: npm run deploy

Output: Secrets are stored in GitHub Secrets and injected as environment variables during CI/CD builds.

Common Mistakes

  1. Committing .env files: Add .env* to .gitignore. Use .env.example as a template for required variables.
  2. Using non-GATSBY_ prefix in client code: Only variables prefixed with GATSBY_ are available in browser JavaScript. Other variables are undefined.
  3. Not loading dotenv in Node.js files: gatsby-config.js and gatsby-node.js need require('dotenv').config() to load .env files.
  4. Hardcoding fallback secrets: Never put real secrets as default values: Process.env.SECRET || 'fallback_secret'.
  5. Missing .env.production in CI: CI/CD pipelines need the production .env file configured via secrets or environment variables.

Practice Questions

  1. What prefix makes environment variables available in browser code? Answer: GATSBY_. Variables like GATSBY_API_URL are available in client code via process.env.GATSBY_API_URL.

  2. How do you load environment variables in gatsby-config.js? Answer: Add require('dotenv').config({ path: .env.${process.env.NODE_ENV} }) at the top.

  3. What is the purpose of .env.example? Answer: It documents which environment variables are required without exposing real values. Developers copy it to create their own .env files.

  4. How do you use different API URLs in dev and production? Answer: Set GATSBY_API_URL in both .env.development and .env.production with different values. The correct one is loaded based on NODE_ENV.

Challenge

Create a feature flag system using environment variables: ENABLE_DARK_MODE, ENABLE_BETA_FEATURES, MAX_UPLOAD_SIZE_MB. Use them in both gatsby-node.js (to control page creation) and in components (to show/hide features).

Mini Project

Set up a multi-environment Gatsby project with: separate Contentful spaces for dev and prod, different analytics IDs per environment, feature flags for in-development features, and a CI/CD pipeline with secrets configured.

FAQ

Can I use `.env.local` for local overrides?

: Yes. Gatsby loads .env.local in addition to environment-specific files. Local overrides take precedence.

How do I access environment variables in CSS?

: Use CSS custom properties injected via JavaScript. Environment variables aren't available in CSS files.

Are environment variables encrypted in the build output?

: No. GATSBY_ variables are embedded in the JavaScript bundle. Don't put sensitive data in GATSBY_ variables.

Can I use environment variables in Graphql queries?

: Not directly. But you can pass them through component logic before or after the query.

What's Next

Learn about Gatsby Deployment to deploy your Gatsby site to production hosting platforms.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro