How to set up environment variables?

What’s the proper way of setting environment variables in netlify? I would like to be able to set different values for the variables depending on the environment.

Pseudo code:

let host;
if (process.env.GATSBY_CUSTOM_CONTEXT === 'production') {
	host = process.env.PRODUCTION_HOST
} else if (process.env.GATSBY_CUSTOM_CONTEXT === 'development') {
	host = process.env.DEVELOPMENT_HOST
}

I have tried passing env variable thru CLI, like GATSBY_CUSTOM_CONTEXT=production gatsby build and I also tried using same command with cross-env.

My other attempt used netlify.toml:

[build]
  base = "/"
  publish = "public"
  command = "yarn build"
  functions = "src/functions"

[context.production]
  [context.production.environment]
    GATSBY_CUSTOM_CONTEXT = "production"

All of these options worked with netlify dev locally, but in production GATSBY_CUSTOM_CONTEXT is always undefined.

I can’t offer an official answer here but in my very limited experience (only been using Functions for 3 days now) the things you put into Netlify’s environment variables config are available at both Function runtime as well as at build time. However, the Netlify “pre-defined” env stuff is only available at build time. Thus, if you want to be able to query the context (production, feature preview, etc.), you can only do so at build time.

What I have done so far is to therefore add a custom webpack config for my functions that uses webpack’s DefinePlugin to “bake in” the context. Also, while I’m there I also bake in the stuff that relies on that rather than doing it at runtime, thus I’d like use prcoess.env.HOST in the code, and in the webpack do something like:

module.exports = {
    plugins: [
        new webpack.DefinePlugin({
            'process.env.HOST': process.env.CONTEXT === 'production'
                ? process.env. PRODUCTION_HOST
                : process.env. DEVELOPMENT_HOST
        })
    ]
}

I’m currently debating whether baking the “final” env vars in is a good idea though, because it means that if you change the env vars in Netlify’s settings, you need to rebuild to get the update, which somewhat breaks an expectation. As such, it might be better to just bake in the context and still “decide” on which env vars to use at runtime based on that.

Anyway, hope this helps.

@iamskok, if you are looking to test if your script is being run in the Netlify build image/environment itself, then one great way to do this is by looking for the environment variable NETLIFY=true. For example:

if (process.env.NETLIFY === 'true') {
 <do something Netlify specific here>
}

We set this environment variable in the build image specifically so CI/CD scripts can make conditional rules/tests for our build environment.

I hope this will meet the requirements for this use case and, either way, please feel free to follow-up with additional comments or questions here. We’re happy to discuss this further.

Thanks for your detailed answer. Were you using netlify-lambda? The issue I’m having is that process.env.CONTEXT is undefined in production.

Yep I’m using netlify-lambda and yes, indeed, CONTEXT is not available in production, hence m e using a custom webpack config (with netlify-lambda) to bake in my env vars based on CONTEXT at build time.

You can either do like I demonstrate above, or just bake in 'process.env.CONTEXT': process.env.CONTEXT to have context available at runtime, so your standard logic can then run.

As I allude to in my post I may change my Functions to work like that soon, because baking in env var at the time of build is not always ideal.

Hi there all, I’m struggling with this one right now and would appreciate any pointers possible.

Since CONTEXT isn’t available to Functions, I’ve been trying to bake it or a subsitute var in somehow but how do you get netlify-lambda to build on the Netlify servers? I can run the netlify-lambda build command locally with webpack config setup for DefinePlugin but then it’s not the context from the deploy that builds on the Netlify Servers.

Those functions will work fine but it’s the same problem as having one set of env vars accessible by all deploys. It’s causing me some major headaches with the different keys needed for using Stripe in test or live mode.

My workaround currently is just going to be having a local .env var that isn’t replicated on Netlify which bakes itself into my build based on my git branch and I have to manually build the functions before pushing to Netlify.

Thanks for any help in advance.

Hi,

The easiest thing to do would be to ‘inject’ the value of ‘CONTEXT’ into a variable inside your function using the following advice:

Instead of using the env var inside your function, you would use sed to replace some placeholder text inside your function.

1 Like

Thank you so much for the reply.

I created a helper file called ‘inject-context.js’ which simply contained:
module.exports = "CONTEXT_PLACEHOLDER"

My other functions imported it and the sed replacement had worked like a charm.

sed -i s/CONTEXT_PLACEHOLDER/${CONTEXT}/g src/functions/helpers/inject-context.js && gatsby build

1 Like

Hi, @Hawks. Thanks for confirming the solution worked for you! We appreciate the follow-up and this will hopefully help others searching our community site for this same issue.