javascriptnode.jsreactjsenvironment-variablesnext.js

Next.js pass NODE_ENV to client


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.


Solution

  • 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

    Another option - 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


    Yet another option - 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