If you have ever written code that looks like this:
const url = `https://www.example.com/api/blog?api_key=${process.env.API_KEY}`
Enter f...
For further actions, you may consider blocking this person and/or reporting abuse
I am working on a project in nextJS written in Typescript. I have gone one step further and implemented a library called Joi to validate .ENV variables. Problem with TypeScript is that it offers no validation on strings really. With Joi you can validate if the string is of the correct length and do validation using regEx.
This way your build will fail if someone did a typo in a crucial .ENV variable. Obviously it won't be bulletproof, but it will provide more confidence than simply checking that the variable isn't undefined.
Don't have to install >500kb package with 5x dependencies.
Another if statement in the config file with regex would let you do that.
I totally agree with you. But somehow got the impression that Joi is super small.
Just looked it up on bundlePhobia.com, but Joi is 145 kB LOL ππ Not sure what I looked up the first time around!??
Back to the drawingboard making my own checks! But the idea is still valid- I think you should validate your ENV. variables...
It seems like a decent library to validate forms and I'd definitely consider it if i had to do enough of all kinds of different validations across the whole app. But then if i do form validation something like that could already be baked into a form package.
In this case seems like a bit of an overkill.
I think I will make my own validation function to handle my use case. I basically want to validate things like string length and various patterns to avoid obvious typos in the. ENV variables.
If you are working with a build tool that supports tree shaking, you might be fine using the package as long as you only import the function you need and not the whole thing. Depends what you are working with
Does this still work?
Not working on my side because of this I think from the nextjs doc:
"Note: In order to keep server-only secrets safe, Next.js replaces process.env.* with the correct values at build time. This means that process.env is not a standard JavaScript object, so youβre not able to use object destructuring. Environment variables must be referenced as e.g. process.env.PUBLISHABLE_KEY, not const { PUBLISHABLE_KEY } = process.env."
Doing process.env.NEXT_PUBLIC_API_URL works, but not process.env['NEXT_PUBLIC_API_URL']
This is awesome! In a recent project we had various discussions of how to check if mandatory env vars are set and how to handle errors in Jenkins pipelines if the vars are not set on deployment target servers.
Being reminded of such simple and efficient solutions is great :)
I don't really see the point of all this. You received a very common error with a simple to find cause and fixed it. Then you wrote a whole post about environment variables in which you overcomplicate the thing entirely.
Most developers that work with Next are expected to know some way to properly deal with environment variables with things like dotenv but let's assume they don't.
Although poor choice of words, I know what you mean there and you are right. It makes sense to say that it shouldn't rely on process.env existing in that context. This is why we separate our application logic, especially with JavaScript. You can of course, write a fetchBlog function that takes one or more arguments.
Somewhere in your utils.js or something:
Often there is not just an API key. With multiple arguments you can do something like this and pass an object.
You can still insist on throwing exceptions simply inside the fetchBlog function.
Tadaa, no matter if apiKey or postId are undefined or the API endpoint itself returns an error because the key/post does not exist or some other reason, you receive proper feedback error message.
But even then, your post started with a typo case. It is useful to ask yourself if a real world situation exists where that could happen, especially if it is your own application. If your code design patterns and abstractions are correct then you will have dealt with the missing environment variable way before any HTTP request is made.
I think it is a bit early to tell people what will make them a better software engineer.
Hey @jochemstoel, I understand your point but I think verifying the necessary API_KEYs at the start of the application would prevent lot's of potential errors and we wouldn't make redundant api calls just to get an error.
This error also could happen during a crutial operation like a purchase or something... I think I'd prefer to check my API KEYS or TOKENS at the start of the application, at least this is what I took from this article.
Also, I understand the article title is a bit provocative but I wouldn't take these kind of things personally. I think author was just trying to get your attention, not to question your skills :D
Have a nice day π
There exists some drawback to this approach though: if you want to package your app in a docker container, that would mean you need your API_KEY at build time in the docker environment and this is a known vulnerability because you would store your API key in the docker layers and it could be accessed within the docker image.
I'm not saying your method is not a good idea (it is) but it shouldn't be so absolute either as it can backfire at you.
Not really right, because your application won't be run inside the docker until you run the image. You'd provide the environment variables with
docker run
command or with a docker-compose file. So there wouldn't be any problems during the build πYes, sorry, it will only happen if you run the
build
command when building your docker container.Actually I really like this approach. It sounds like a best practice to me.
I have library to read environment variables as application config. I was thinking to add it to the library, having an option like
mandatoryKeys
but then I left it to users to validate the keys. Maybe adding that option and making it mandatory to define could force this practice. If they don't want to validate the keys they'll have to definemandatoryKeys: []
for instance. I'll think about it.yatki / read-env
π§ Transform environment variables into JSON object with sanitized values.
read-env
Main purpose of this library is to allow developers to configure their applications with environment variables. See: a use case example.
What's New with v2.xπ
separator
option,nested object constructions are possible.source
option allows you to use other objects, other thanprocess.env
Migrating from v1.x to v2.x
default
export is deprecated. Please use named exportreadEnv
as below:parse
option was renamed assanitize
.transformKey
option was renamed asformat
.ignoreInvalidJSON
,prefix
,filter
,Install
or
Basic
β¦Thanks for the tip.
Cheers, ππ
I used to add auto-completing to my env vars using TypeScript like this:
While I'm coping your function add a small type:
But, unfortunately, seems like the
keyof NodeJS.ProcessEnv
does NOT work.Do you have any idea how to solve this?
I believe this statement if factually incorrect. The application will compile and will run into a runtime exception upon startup and crash the server.
Provided approach will not validate if all env variables exist before trying to run the server. Correct me if am wrong.
Can you suggest an approach to validate existence of all Env Vars during
nest build
step?Env Var is a perfect package for this npmjs.com/package/env-var
You can make a variable as required, parse from base64, other types. Itβs been my goto recently
Great suggestion. That package looks great for this purpose.
Thanks for the idea. To truly get it to throw during build, I added a custom plugin to the webpack config, similar to: stackoverflow.com/a/72277530