Home Blog Jekyll Environment Variables: The Complete Guide
Tutorial

Jekyll Environment Variables: The Complete Guide

How to use environment variables in Jekyll — JEKYLL_ENV, accessing env vars in config, conditional builds, and best practices for managing secrets.

Jekyll Environment Variables: The Complete Guide

Environment variables in Jekyll are simpler than you might expect — but also more limited than many developers assume coming from Node.js or Python. Here is everything you need to know.

JEKYLL_ENV: the key environment variable

Jekyll ships with one built-in environment variable: JEKYLL_ENV. It defaults to development when you run jekyll serve or jekyll build locally. To set it to production, prefix your build command:

JEKYLL_ENV=production jekyll build

On Netlify, Cloudflare Pages, and most CI platforms, this is set automatically.

Using JEKYLL_ENV in Liquid templates

You can read the environment in your templates using jekyll.environment:


{% if jekyll.environment == "production" %}
  {% include analytics.html %}
{% endif %}

This is the standard pattern for including analytics, chat widgets, and other scripts only in production builds — keeping your development output clean and your test data separate from real analytics.

Common production-only includes


{% comment %} In _layouts/default.html {% endcomment %}
{% if jekyll.environment == "production" %}
  {% include analytics.html %}
  {% include cookie-banner.html %}
{% endif %}

Can Jekyll read system environment variables?

Yes — but only through _config.yml using ERB interpolation, and only when Jekyll is run with the --config flag pointing to a .yml file processed as ERB. This is not supported out of the box in standard Jekyll.

The most reliable approach for secrets in Jekyll is to use your hosting platform’s environment variable system and inject values at build time.

Injecting environment variables via _config.yml on Netlify

Netlify lets you set environment variables in your site dashboard (Site settings → Environment variables). You can then reference them in netlify.toml:

[build]
  command = "JEKYLL_ENV=production jekyll build"
  publish = "_site"

[build.environment]
  JEKYLL_ENV = "production"

For values you want available in your Liquid templates, the cleanest approach is to set them in _config.yml directly — keeping non-secret config in version control and only truly secret values (API keys, tokens) in the platform’s environment variable system.

Environment-specific config files

Jekyll supports multiple config files merged at build time. This is the recommended pattern for environment-specific settings:

# Development (default)
jekyll serve

# Production
jekyll build --config _config.yml,_config.production.yml

# Staging
jekyll build --config _config.yml,_config.staging.yml

Your _config.production.yml overrides only the values that differ:

# _config.production.yml
url: "https://yourdomain.com"
google_analytics: "G-XXXXXXXXXX"
show_drafts: false

Your _config.yml keeps safe defaults:

# _config.yml
url: "http://localhost:4000"
google_analytics: ""
show_drafts: true

Practical examples

Analytics only in production


{% comment %} _includes/analytics.html {% endcomment %}
{% if jekyll.environment == "production" and site.google_analytics != "" %}
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics }}"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag("js", new Date());
  gtag("config", "{{ site.google_analytics }}");
</script>
{% endif %}

Draft posts visible in development only

# _config.yml
show_drafts: false

# _config.development.yml  
show_drafts: true
jekyll serve --config _config.yml,_config.development.yml --drafts

Different base URLs per environment

# _config.yml
url: "https://jekyllhub.com"
baseurl: ""

# _config.staging.yml
url: "https://staging.jekyllhub.com"
baseurl: "/staging"
# _config.yml
maintenance_mode: false

{% if site.maintenance_mode %}
  <div class="maintenance-banner">We are performing maintenance. Back shortly.</div>
{% endif %}

What you cannot do directly

Jekyll does not have a .env file loader like Node.js projects. You cannot write:

# This does NOT work in Jekyll
API_KEY=abc123

…and then access `` in a template. Jekyll does not read shell environment variables into the Liquid context.

If you need to expose an API key to client-side JavaScript, remember that anything in your built _site folder is public. Never embed secret API keys in static HTML. Use a proxy function (Netlify Functions, Cloudflare Workers) to make authenticated requests from the server side.

Summary

Pattern Use case
JEKYLL_ENV=production Toggle analytics, ads, and scripts
Multiple _config files Environment-specific URLs and settings
Platform env vars in netlify.toml Inject build-time values
jekyll.environment in Liquid Conditional template logic

Keep your environment strategy simple. For most Jekyll sites, JEKYLL_ENV plus a production config override covers everything you need.

Share LinkedIn