Next.js: My .env variables just don't work!

Created on 13 May 2019  ·  15Comments  ·  Source: vercel/next.js

Bug report

every .env variable fails to show up even by using process.env.VARIABLE clause.

To Reproduce

  • next.config.js:
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass')
const { parsed: localEnv } = require('dotenv').config()
const webpack = require('webpack')

module.exports = withSass({
  webpack(config) {
    config.plugins.push(new webpack.EnvironmentPlugin(localEnv))
    config.plugins.push(
      new webpack.ProvidePlugin({
          '$': 'jquery',
          'jQuery': 'jquery',
      })
    )
    return config
  }
})
  • constants.js:
export const BACKEND_SERVER = process.env.BACKEND_SERVER
export const PROD_DOMAIN = process.env.PROD_DOMAIN
export const FB_LOGIN_APP_ID = process.env.FB_LOGIN_APP_ID
export const GOOGLE_LOGIN_APP_ID = process.env.GOOGLE_LOGIN_APP_ID
export const GOOGLE_LOGIN_APP_SECRET = process.env.GOOGLE_LOGIN_APP_SECRET
export const FB_LOGIN_APP_VERSION = process.env.FB_LOGIN_APP_VERSION
export const DEV_DOMAIN = process.env.DEV_DOMAIN
export const ENDPOINT = process.env.ENDPOINT
export const GA_TRACKING_ID = process.env.GA_TRACKING_ID
export const CLOUDINARY_USERNAME = process.env.CLOUDINARY_USERNAME
  • App.js
import { BACKEND_SERVER } from './constants'
export const client = new ApolloClient({
  uri: `${BACKEND_SERVER}/graphql`,
  request: operation => {
    operation.setContext({
      fetchOptions: {
        credentials: 'include',
      }
    })
  }
})

Expected behavior

The above example should make env variable work nicely, but just doesn't!

System information

  • OS: macOS 18.0.0
  • Browser (if applies) Chrome Latest
  • Version of Next.js: v7.0.2

Additional context

Please help, trying to solve the bug since two days!

Most helpful comment

You should be able to upgrade to v8 from v7.0.2 to do so you do yarn add next@latest react@latest react-dom@latest

To have better compatibility with Now and Heroku I would use process.env to access the values. So in development you can use dotenv to load your values and then in production they will be added to the environment by configuring them on the platform you are using. Here are the docs for configuring them on Now.

So your next.config.js would look like this:

require('dotenv').config()
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass')
const webpack = require('webpack')

module.exports = withSass({
  webpack(config) {
    config.plugins.push(
      new webpack.ProvidePlugin({
          '$': 'jquery',
          'jQuery': 'jquery',
      })
    )
    return config
  },
  env: {
    'MY_SECRET_KEY': process.env.MY_SECRET_KEY
  }
})

This will allow you to use process.env.MY_SECRET_KEY in your built files.
Note: if you change these values you will need to run a new build.

All 15 comments

Hi, have you tried using the built-in support for inlining values during build? Here are the docs in case you missed them.

Thanks, @ijjk! I looked at docs and wondered if it could help me. But I am not gitignoring next.config.js to put env variables in there.
And if I do, how do I do what's written docs on current configuration of my next.config.js?

You can still use dotenv just set the env option to your localEnv instead of using webpack.EnvironmentPlugin. Looks like you'll need to upgrade Next.js versions though since you're still on v7.0.2 and this was introduced in v8

Are you sure, that if I update Nextjs, things won't break? Is it backward-compatible? What do I need to do to upgrade Nextjs? Does updating next npm package do the trick? Please help.

The code I am using doesn't load the env in production on platforms like Now and Heroku.

You should be able to upgrade to v8 from v7.0.2 to do so you do yarn add next@latest react@latest react-dom@latest

To have better compatibility with Now and Heroku I would use process.env to access the values. So in development you can use dotenv to load your values and then in production they will be added to the environment by configuring them on the platform you are using. Here are the docs for configuring them on Now.

So your next.config.js would look like this:

require('dotenv').config()
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass')
const webpack = require('webpack')

module.exports = withSass({
  webpack(config) {
    config.plugins.push(
      new webpack.ProvidePlugin({
          '$': 'jquery',
          'jQuery': 'jquery',
      })
    )
    return config
  },
  env: {
    'MY_SECRET_KEY': process.env.MY_SECRET_KEY
  }
})

This will allow you to use process.env.MY_SECRET_KEY in your built files.
Note: if you change these values you will need to run a new build.

Sorry for this silly question 😅

But where will MY_SECRET_KEY exist? In .env file, right?

I tried the way you shown, just doesn't work. Everything broke. 😅

Did you upgrade Next.js to v8 first? Looking at https://github.com/KumarAbhirup/paprink/blob/development/package.json it is still on v7.0.2.

Saying everything broke doesn't really help since that could mean almost anything. Error messages and links to the repo help a lot.

In the server-side source, env values are rendered properly.

For eg,

  • this code worked:
<script dangerouslySetInnerHTML={{__html: `
            window.fbAsyncInit = function() {
              FB.init({
                appId      : '${process.env.FB_LOGIN_APP_ID}',
                cookie     : true,
                xfbml      : true,
                version    : '${process.env.FB_LOGIN_APP_VERSION}'
              });
              FB.AppEvents.logPageView();  
            };
            (function(d, s, id){
              var js, fjs = d.getElementsByTagName(s)[0];
              if (d.getElementById(id)) {return;}
              js = d.createElement(s); js.id = id;
              js.src = "https://connect.facebook.net/en_US/sdk.js";
              fjs.parentNode.insertBefore(js, fjs);
            }(document, 'script', 'facebook-jssdk'));
          `}}></script>
  • Result:
    Screenshot 2019-05-13 at 10 54 23 PM

Things look good on server, but things broke then. It threw these errors in the console 👇

Uncaught uO {message: "Missing required parameter 'client_id'", stack: "gapi.auth2.ExternallyVisibleError: Missing require…9cnbqtYcGbV-WNAmJljNpys4lNg/cb=gapi.loaded_0:1:15"}
Uncaught: b {message: "init not called with valid version", innerError: undefined}

Oh yes, you caught it very right, I haven't yet updated nextjs, will get back when done.

You are god ❤️ @ijjk, it's working after the update. Just that I need to check if things are working on production or not. Wish me luck.

Saying everything broke doesn't really help since that could mean almost anything. Error messages and links to the repo help a lot.

Everything broke is just my way of expressing that I am sad 😅 Sorry if that sounds rude. 15 yo kid learning here.

Cool, good luck 👍 I'm gonna close this issue now, if you're still having trouble with this feel free to comment again.

Hi @ijjk, hitting back here again.
The same problem, but a different repo. Now when I try your solution, env doesn't work.
I am implementing something the wrong way probably 😅

https://github.com/iqubex-technologies/adify/tree/d5a92640f1b45df3afb6e03125778ef320a84b1d

Access the Next.js website in the web directory.

You should be able to upgrade to v8 from v7.0.2 to do so you do yarn add next@latest react@latest react-dom@latest

To have better compatibility with Now and Heroku I would use process.env to access the values. So in development you can use dotenv to load your values and then in production they will be added to the environment by configuring them on the platform you are using. Here are the docs for configuring them on Now.

So your next.config.js would look like this:

require('dotenv').config()
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass')
const webpack = require('webpack')

module.exports = withSass({
  webpack(config) {
    config.plugins.push(
      new webpack.ProvidePlugin({
          '$': 'jquery',
          'jQuery': 'jquery',
      })
    )
    return config
  },
  env: {
    'MY_SECRET_KEY': process.env.MY_SECRET_KEY
  }
})

This will allow you to use process.env.MY_SECRET_KEY in your built files.
Note: if you change these values you will need to run a new build.

I know this is a while afterwards but this should be the accepted solution. I just ran into this same problem but this fixed it with flying colors! Thanks!

You should be able to upgrade to v8 from v7.0.2 to do so you do yarn add next@latest react@latest react-dom@latest

To have better compatibility with Now and Heroku I would use process.env to access the values. So in development you can use dotenv to load your values and then in production they will be added to the environment by configuring them on the platform you are using. Here are the docs for configuring them on Now.

So your next.config.js would look like this:

require('dotenv').config()
const withCSS = require('@zeit/next-css');
const withSass = require('@zeit/next-sass')
const webpack = require('webpack')

module.exports = withSass({
  webpack(config) {
    config.plugins.push(
      new webpack.ProvidePlugin({
          '$': 'jquery',
          'jQuery': 'jquery',
      })
    )
    return config
  },
  env: {
    'MY_SECRET_KEY': process.env.MY_SECRET_KEY
  }
})

This will allow you to use process.env.MY_SECRET_KEY in your built files.
Note: if you change these values you will need to run a new build.

what if you wanna have a different value in .env.development and another in .env.production ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sospedra picture sospedra  ·  3Comments

renatorib picture renatorib  ·  3Comments

timneutkens picture timneutkens  ·  3Comments

YarivGilad picture YarivGilad  ·  3Comments

havefive picture havefive  ·  3Comments