Next.js pass NODE_ENV to client

Using Next's build-time configuration

@DarrylR already mentioned using next.config.js and Next's runtime configuration, but you can also use Next's build-time configuration.

This lets you put the process.env.XXXX right into the code (as shown in step 3 below), and you don't have to import anything. However, if you env variables should be set both when you build locally with Next.js and when you deploy to ZEIT Now, I don't know if you can keep them in just one file using this method (see step 2 below).

The runtime configuration docs suggest you normally want to use build-time configuration:

Warning: Generally you want to use build-time configuration to provide your configuration. The reason for this is that runtime configuration adds rendering / initialization overhead and is incompatible with automatic prerendering.


Steps:

1. Set NODE_ENV for build process

1.1 Using ZEIT Now

If you deploy using ZEIT Now, you can set the env variables used at build time in now.json:

{
  "version": 2,
  "build": {
    "env": {
      "NODE_ENV": "production"
    }
  }
}

1.2 When running locally (optional)

If you want NODE_ENV to be set when running locally as well, this will not be set by now.json. However you can set it in other ways, such as:

$ NODE_ENV=production npm run build

or change the build script in package.json to

"build": "NODE_ENV=production next build"

You can of course also set NODE_ENV for other scripts than build if you want that.

2. Make Next inline value of process.env.NODE_ENV

Add this to the next.config.js as described here:

module.exports = {
  env: {
    NODE_ENV: process.env.NODE_ENV
  }
};

3. Use in code

if (process.env.NODE_ENV === "production") {
  console.log("In production")
} else {
  console.log("Not in production")
}

Since Next.js 9.4, NextJs has now built-in support for environment variables, which allows you to do the following using .env files:

An example .env.local:

DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword

If you want to expose the env variables to the client, you have to prefix the variable with NEXT_PUBLIC_ for example:

NEXT_PUBLIC_API_PORT=4000

If you want to use the variable, you can use it like this: process.env.NEXT_PUBLIC_API_PORT

For the documentation see here


Another Easy solution:

create 2 files on root folder:

.env.development
.env.production

inside add variables as you need, for example in .env.development file:

NEXT_PUBLIC_ENV="development"

and in .env.production file:

NEXT_PUBLIC_ENV="production"

Then use it for example:

console.log('Version: ', process.env.NEXT_PUBLIC_ENV);

1. You can include it in webpack configuration (using dotenv-webpack dependency):

require('dotenv').config()

const path = require('path')
const Dotenv = require('dotenv-webpack')

module.exports = {
  webpack: (config) => {
    config.plugins = config.plugins || []

    config.plugins = [
      ...config.plugins,

      // Read the .env file
      new Dotenv({
        path: path.join(__dirname, '.env'),
        systemvars: true
      })
    ]

    return config
  }
}

Reference: here


2. using babel plugin to import the variable towards the entire app:

env-config.js

const prod = process.env.NODE_ENV === 'production'

module.exports = {
  'process.env.BACKEND_URL': prod ? 'https://api.example.com' : 'https://localhost:8080'
}

.babelrc.js

const env = require('./env-config.js')

module.exports = {
  presets: ['next/babel'],
  plugins: [['transform-define', env]]
}

index.js

export default () => (
  <div>Loading data from { process.env.BACKEND_URL }</div>
)

Reference: here

3. Using next/config:

next.config.js

module.exports = {
  publicRuntimeConfig: {
    API_URL: process.env.API_URL
  }
}

index.js

import React from 'react'
import getConfig from 'next/config'

const {publicRuntimeConfig} = getConfig()
const {API_URL} = publicRuntimeConfig

export default class extends React.Component {
  static async getInitialProps () {
    // fetch(`${API_URL}/some-path`)
    return {}
  }

  render () {
    return <div>
            The API_URL is {API_URL}
    </div>
  }
}

Reference: here