Environment variables on Netlify are how you inject configuration and secrets into your deployed sites, and the most surprising thing is how easily you can accidentally expose sensitive data if you don’t understand their scope.

Let’s see it in action. Imagine a simple static site with a form that needs to send data to an external service. That service likely requires an API key.

Here’s a netlify.toml file that defines a build-time environment variable:

[build]
  command = "npm run build"
  publish = "public"

[build.environment]
  API_KEY = "my_super_secret_api_key_for_build"

During the build process, npm run build can access process.env.API_KEY. If your build process embeds this key directly into your JavaScript bundle (which is a common, and often dangerous, mistake), it’s now client-side and visible to anyone inspecting your site’s source code.

Now, consider a function that needs to access a secret at runtime. For example, a Netlify Function that processes form submissions and sends them to a third-party API. You’d configure this in the Netlify UI under "Site settings" -> "Build & deploy" -> "Environment".

Let’s say you add THIRD_PARTY_API_SECRET with the value super_secret_runtime_value.

KEY: THIRD_PARTY_API_SECRET
VALUE: super_secret_runtime_value

This variable is then available to your Netlify Functions. Your function code might look like this:

// netlify/functions/process-form.js
exports.handler = async (event, context) => {
  const apiSecret = process.env.THIRD_PARTY_API_SECRET;

  // ... use apiSecret to call the third-party API ...

  return {
    statusCode: 200,
    body: JSON.stringify({ message: "Form processed" }),
  };
};

This is much safer because THIRD_PARTY_API_SECRET is only exposed to the server-side function, not bundled into your client-side JavaScript.

The core problem Netlify environment variables solve is securely providing configuration to your application without hardcoding it directly into your codebase. This is crucial for:

  • Secrets Management: API keys, database credentials, tokens.
  • Configuration: Service endpoints, feature flags, third-party integrations.
  • Environment-Specific Settings: Different API keys for staging vs. production.

Netlify offers several scopes for environment variables:

  1. Build-time: Available only during the build process. Set in netlify.toml or via the UI under "Build settings". These are injected into the build environment (e.g., your npm install or npm run build commands).
  2. Runtime (Functions): Available to your Netlify Functions. Set in the UI under "Environment" for your site. These are injected into the execution environment of your serverless functions.

The distinction between build-time and runtime is critical. If you put a secret intended for a Netlify Function into a [build.environment] block in netlify.toml, it will be available to your build process and could potentially leak into your client-side bundle if not handled carefully.

The most common mistake is placing secrets that should only be accessed by Netlify Functions into the [build.environment] section of netlify.toml. These variables are exposed to the build agent and, if your build process is not careful, can end up embedded in your client-side code, making them public. Always use the "Environment" section in the Netlify UI for secrets that are only needed by your serverless functions.

When you set an environment variable in the Netlify UI under "Environment," you can choose its scope: "All environments," "Production," "Deploy previews," or "Development." For secrets, you typically want to restrict them to "Production" or specific branches. Additionally, you can mark them as "Un মত " (untrusted), which prevents them from being exposed to client-side JavaScript, even if they are set at build time. This "Un মত " flag is a safeguard against accidental client-side leakage.

The next thing you’ll likely grapple with is managing these variables across different environments (dev, staging, prod) and the implications of using Git-based configuration like netlify.toml versus UI-based configuration for sensitive data.

Want structured learning?

Take the full Netlify course →