DEV Community

Daniel Blackwell
Daniel Blackwell

Posted on • Edited on

Nuxt.js Environment Variables (without dotenv)

This article covers Nuxt for versions 2.12 and below.
For 2.13 and above, you can now use $config with publicRuntimeConfig and privateRuntimeConfig

Nuxt's process.env works in mysterious ways. Hopefully this demystifies some of it. I'm going to cover the dotenv module in another post.

  1. Webpack replaces process.env.YOUR_VARIABLE
  2. Access variables using context.env
  3. Automatic variables using NUXT_ENV_
  4. Declared variables using nuxt.config.js

Webpack replaces process.env.YOUR_VARIABLE client-side

Imagine I set a system environment variable NUXT_ENV_COOL_WORD with the value jabberwocky.
When the client side JS is generated, the literal string process.env.NUXT_ENV_COOL_WORD is replaced, by Webpack, with 'jabberwocky' in the generated client JS.
This code snippet will work client side:

<template>
    <pre>
    {{processEnv}}
    </pre>
</template>
<script>
export default { 
  data() { return { processEnv: process.env.NUXT_ENV_COOL_WORD } }
}
</script>

with the generated client JS containing

    var o = {data: function() {
            return { processEnv: "jabberwocky" };
          }},

The following example doesn't won't work on the client side in the standard setup:

<template>
    <pre>Will be empty: {{processEnv.NUXT_ENV_COOL_WORD}}</pre>
</template>
<script> 
// DOESN'T WORK ON THE CLIENT RENDERED HTML
// BUT DOES ON SERVER RENDERED HTML
export default { data() { return { processEnv: process.env }}
</script>

The value of NUXT_ENV_COOL_WORD will show when the server side html is loaded, which then immediately disappears as the client side SPA JS kicks in. Although the string is not replaced on the server side generation, all environment variables are available server side.

Access variables client-side with context.env

Although direct access through process.env doesn't work client-side, there is still a way to use the variables.
The Nuxt.js context is populated with the declared and automatic variables.

Example of the generated code:

   app.context = {
      isStatic: process.static,
      isDev: true,
      isHMR: false,
      app,

      payload: context.payload,
      error: context.error,
      base: '/',
      env: {"NUXT_ENV_COOL_WORD":"this is pretty cool"}
    }

context is provided to:

  • asyncData
  • fetch
  • middleware
  • plugins
  • nuxtServerInit (server only)

example.vue

<template>
   <pre>
     async: {{myAsyncEnv}}
     fetch: {{myFetchEnv}}
   </pre>
</template>

<script>
export default {
  middleware: ["my-middleware"], 
  asyncData({env}){
    return { myAsyncEnv: env.NUXT_ENV_COOL_WORD }
  },
  fetch({env}){
    this.myFetchEnv = env.NUXT_ENV_COOL_WORD
  }
}
</script>

my-middleware.js

export default function({ env }) {
  console.log(env.NUXT_ENV_COOL_WORD);
}

Automatic env variables using NUXT_ENV_

The Nuxt.js ENV page states

If you define environment variables starting with NUXT_ENV_ in the build phase (f.ex. NUXT_ENV_COOL_WORD=freezing nuxt build, they'll be automatically injected into the process environment.

If there is a environment variable that starts with NUXT_ENV_, then that key AND value will be included in the generated JS files, and will be available from process.env on both the server and client side.

If there is no NUXT_ENV_, then the variable will not be included in the client side JS automatically; and therefore:

  • CAN'T be used Client side,
  • but CAN still be used Server side

This can be tested by:

  1. Adding NUXT_ENV_COOL_WORD to your System Environment variables,
  2. Restarting just to be sure it's on all processes
  3. Test using the working example above

There is a way to get this to work using the dotenv module. That will be in another post.

Declared env variables using the nuxt.config.js

Within nuxt.config.js, one can define (pseudo) environment variables.
These can be used client and server side without issues, as well as to pass along environment variables that don't have the NUXT_ENV_ prefix

export default {
/* ... */
  env: {
    NUXT_ENV_COOL_WORD: "a default value that can be overridden",
    SOME_OTHER_VALUE: "can't be overridden - missing NUXT_ENV_ prefix",
    CONDITIONAL: process.env.CONDITIONAL || "some default value" //if can't use NUXT_ENV_
    SOME_VARIABLE: process.env.SOME_VARIABLE // Ensure variable reaches the client
  }
}

These variables are also available on the context.env

Variables with the NUXT_ENV_ are OVERRIDDEN by environment variables of the same name. This is very useful for development.

Hope this helps!

Top comments (4)

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
deeja profile image
Daniel Blackwell

If the env is incoming, within the nuxt.config.js you can access it using the process.env.VARIABLENAME

 privateRuntimeConfig: {
       VARIABLENAME: process.env.VARIABLENAME
}
Enter fullscreen mode Exit fullscreen mode

If it's not incoming, then you can set it and use it within the file.

const myVariable = "something"

 privateRuntimeConfig: {
       VARIABLENAME: myVariable
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mgrachev profile image
Grachev Mikhail

In addition to using environment variables I can recommend the tool github.com/dotenv-linter/dotenv-li... - it’s a lightning-fast linter for .env files. Written in Rust.
Maybe it would be useful for you.

Collapse
 
slidenerd profile image
slidenerd

how do I set separate environment variables for from .env.test, .env.debug, .env.dev and .env.prod using this?