Next.js pass NODE_ENV to client

33,469

Solution 1

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

Solution 2

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")
}

Solution 3

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);

Solution 4

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

Share:
33,469

Related videos on Youtube

Jack Wild
Author by

Jack Wild

Updated on December 27, 2021

Comments

  • Jack Wild
    Jack Wild over 2 years

    I'm building a React SSR App, using Next.js.

    I want to be able to access the NODE_ENV on the client side, as this will tell my app which API endpoints to use.

    I'm struggling to find a decent approach for this. I'd like to define the NODE_ENV as a window variable when I first render the page on the server, and then in my helper function where I make the API call, I would check if the code is being called on the server or the client, and using the window or process.env objects as required.

    Does anyone have a good solution for such a problem? It must be a common issue but I can't find any good solutions.

  • Jack Wild
    Jack Wild over 5 years
    Thanks, this is an extremely helpful answer!
  • Matteo
    Matteo about 5 years
    I think the last one is the best solution, Thanks!
  • HRoux
    HRoux about 4 years
    I tried this solution but NODE_ENV is not allow in next.config.js in my case : github.com/zeit/next.js/blob/master/errors/…
  • SalahAdDin
    SalahAdDin almost 4 years
    Is it required for the last NextJS version?
  • Darryl RN
    Darryl RN over 3 years
    @SalahAdDin it depends on your system design. if you combine backend (e.g: nodejs) and frontend NextJS in one project or using SSR from NextJS then env configuration still required, and if you want to pass it to frontend you can use the above ways. Otherwise, like using static export NextJS you don't need this one.
  • Yeats
    Yeats over 3 years
    You forgot the actual answer. You just talk about how to use the variable, not how to set it up....
  • ArneHugo
    ArneHugo over 3 years
    In step 1 and 2 I try to explain how to set it up. Can you explain what part of it is missing or confusing? (Actually, not sure if you mean me or the first comment.)