Nuxt.js Environment Variables (without dotenv)
Tags: vue, javascript, nuxt, env
Published: 2020-05-24 17:16:04

_This article covers Nuxt for versions 2.12 and below. 
For 2.13 and above, [you can now use `$config` with `publicRuntimeConfig` and `privateRuntimeConfig`](https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config)_


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`](#webpack)
1. [Access variables using `context.env`](#context)
1. [Automatic variables using  `NUXT_ENV_`](#nuxtenv)
1. [Declared variables using `nuxt.config.js`](#nuxtconfig)


<a name="webpack"></a>
### 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:
```vue
<template>
    <pre>
    {{processEnv}}
    </pre>
</template>
<script>
export default { 
  data() { return { processEnv: process.env.NUXT_ENV_COOL_WORD } }
}
</script>
```
with the generated client JS containing
```js
    var o = {data: function() {
            return { processEnv: "jabberwocky" };
          }},
```

The following example *doesn't* won't work on the client side in the standard setup:
```vue
<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. 
<a name="context"></a>
## 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](https://nuxtjs.org/api/context/) is populated with the declared and automatic variables. 

Example of the generated code:
```js
   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`
```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`
```js
export default function({ env }) {
  console.log(env.NUXT_ENV_COOL_WORD);
}
```
<a name="nuxtenv"></a>
## Automatic `env` variables using `NUXT_ENV_`

The [Nuxt.js ENV page](https://nuxtjs.org/api/configuration-env/) 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,
1. Restarting just to be sure it's on all processes
1. 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. 
<a name="nuxtconfig"></a>
## 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
```js
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!