Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting undefined #7

Open
aarcoraci opened this issue Aug 2, 2018 · 17 comments
Open

Getting undefined #7

aarcoraci opened this issue Aug 2, 2018 · 17 comments
Labels
help wanted Extra attention is needed

Comments

@aarcoraci
Copy link

Hello,
I'm trying to get this module working but no luck. I have followed the steps stated:

  1. added dependency via yarn
  2. added the module and configure it using a key from the env section of nuxt.config.js
  3. when I use it I get undefined every time.
  modules: [
    "bootstrap-vue/nuxt", 
    "cookie-universal-nuxt", 
    ['nuxt-env', {
      keys: ['baseUrl']
    }]
  ],
export default {
 mounted(){
   console.log(this.$env.baseUrl);  // undefined
   console.log(process.env.baseUrl); // correct url   
 }
};
@ezynda3
Copy link

ezynda3 commented Aug 22, 2018

I'm getting the same error even when I wrap in this.$nextTick()

@samtgarson
Copy link
Owner

How are you injecting your environment variables?

@saratitan
Copy link

Mine are undefined in spa mode

@samtgarson
Copy link
Owner

If this is still occuring can someone use code sandbox to recreate this, so I can debug?

@aalenliang
Copy link

I think @aarcoraci means, in nuxt.config.js

module.exports = {
  env: {
    baseUrl: 'some thing'
  },
  ...
  modules: [
    ['nuxt-env', {
      keys: ['baseUrl']
    }]
  ],
  ...
}

and with the output of this.$env.baseUrl === undefined?

i am confused at first, and realize the key means key of the actual process.env that is accessible in nuxt.config.js file, like:

// BASE_URL=https://example.com npm run dev
// this.$env.BASE_URL === 'https://example.com'

['nuxt-env', {
  keys: ['BASE_URL']
}]

@samtgarson
Copy link
Owner

Currently this module does not support SPA mode, as for that you can just use the normal env property and the vars will get baked in at build time.

I'm working on support for this but I'm not quite sure what it, any ideas would be appreciated.

@samtgarson samtgarson added the help wanted Extra attention is needed label Feb 14, 2019
@rmeissn
Copy link

rmeissn commented Mar 22, 2019

Idea for SPA mode (if possible with current nuxt):

  1. register a startup hook (as of nuxt start or whatever brings up the server to serve the SPA). In this hook:
  2. read your list of desired env vars, get the value from the env vars of the system and paste them to a file (so that the name and value of the env var is hardcoded)
  3. add into some basic step of the SPA to download and execute the file from 2.
  4. run a little routine to add every existing env var in the downloaded file to process.$env

@simplesmiler
Copy link

simplesmiler commented Jul 25, 2019

There is a related discussion about making runtime env vars supported out of the box: nuxt/nuxt#5100.

@MarlBurroW
Copy link

MarlBurroW commented Sep 23, 2019

@samtgarson Maybe you should alter the nuxt server nuxt start to add a custom header on each response containing serialized env variables.
And on the client side, make a small script to populate app.$env with the payload shipped in the response header. I'm not sure you can read the headers of the initial response from js, but if you can't, you can use the Set-Cookie header through document.cookie.

EDIT: Tested with a serverMiddleware in spa mode, and it works:

// nuxt.config.js
export default {
  mode: 'spa',
  // ...
  serverMiddleware: [
    function(req, res, next) {
      // Authorized env variables to be sent to the client
      const allowed = ['BACKEND_URL', 'BACKEND_PORT']

      // Filter process.env with allowed env variables
      const filtered = Object.keys(process.env)
        .filter(key => allowed.includes(key))
        .reduce((obj, key) => {
          obj[key] = process.env[key]
          return obj
        }, {})
      
      // Set the ENV cookie with JSON encoded variables
      res.setHeader('Set-Cookie', [`ENV=${JSON.stringify(filtered)}`])
      next()
    }
  ],
  // ...
}

Maybe a track to explore...

@samtgarson
Copy link
Owner

That is an interesting one—I also recently saw this implementation which uses the head metadata to store the public env...

(unfortunately this repo also includes "shims" for other libraries which I strongly disagree with 😞 )

Not sure which personally I prefer as both are using mechanisms which are not designed for this, but if I had to chose I think I'd chose the head meta route... I always shy away from setting cookies where possible 🍪

Don't have any time right now to work on this but would definitely look at PRs!

@MarlBurroW
Copy link

OK got your point, I agree but if you exclude the hacky option (meta/cookie), I guess the only "proper" option requires some async stuff:

  • Add a route to the nuxt start server and make it serves a json representation of the allowed environments variables (defined in the nuxt.config).
  • Fetch the route from the client very early + JSON.parse the response body + assign the result object to Vue.prototype.$env + probably need to return a promise somewhere to deal with async.

If this kind of option sounds ok for you, I'll try to make a PR.

@samtgarson
Copy link
Owner

Yeah, that is an alternative but of course its an extra HTTP request so has performance/network implications, plus seems more fragile to your point about dealing with async-ness.

I'd be happy with either of the meta/cookie options right now 👍

@itsrachelfish
Copy link

Really glad I found this conversation. Hard to believe Nuxt still has this limitation. Big problem for projects that use CI/CD build servers.

@marcpaskell
Copy link

marcpaskell commented Dec 3, 2019

Useful thread, thanks. Are there plans to support a 12 factor style approach for env vars in SPA mode from the nuxt core team or would it need to come through this project? Cheers.

@MartinMuzatko
Copy link

MartinMuzatko commented Feb 18, 2020

There is a very easy trick that works with SPA mode:

app.html

<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    <script>window.ENV = {{ ENV_INJECT }}</script>
    {{ APP }}
  </body>
</html>

add this to your nuxt.config.js:

const { map, fromPairs, defaultTo } = require('ramda')
{
    hooks: {
        'vue-renderer:spa:templateParams': meta => {
            const injectVariablesWithDefaults = [
                ['INITIAL_SETUP', false],
            ]
            const processEnvDefault = ([key, defaultValue]) => [key, defaultTo(defaultValue, process.env[key])]
            const injectVariables = fromPairs(map(processEnvDefault, injectVariablesWithDefaults))
            meta.ENV_INJECT = JSON.stringify(injectVariables)
        }
    },
}

This picks the desired environment variables from process.env and injects them to the global window object.
This is designed for spa mode *only, since the window object will be not available during SSR.

Surely there is a way to also append to the other meta variables like APP. But I wanted to be future proof, in case they change the order of hooks or overwrite the variable again somehow.
See here: https://github.com/nuxt/nuxt.js/blob/b17f331fe51bb85776213988eb13559342955fcd/packages/vue-renderer/src/renderers/spa.js

Also: you can write this without ramda. I just found it to be easier for me.

Best,
Martin :)

@coderua

This comment has been minimized.

@samtgarson
Copy link
Owner

samtgarson commented Apr 22, 2020

@coderua that is a different issue, please don't hijack the thread—the error is saying that this is undefined.

This suggests to me your store is not being setup like a normal store. Could you take another look as to why that might be, it's not really within the scope of this library to fix but if you're still stuck please open another ticket with an expanded snippet of your store and I might be able to help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests