This post was originally published on October 9, 2020 on my blog.
Good morning and happy Friday! I've run into a bit of an issue - that I know I've solved before by putting a sort of band-aid solution on it - but I want to solve it fully now and I'm running into a bit of a wall.
Essentially, I have a static website running on simple HTML, CSS, and JavaScript. I'm currently fetching data from my podcast host API so that I can display podcast episodes without having to hardcode all of the podcast data into my own JS files.
Now, where I'm running into my issue is that I want to use an environment variable for my API access key in a .env file, but I can't use the 'require' function in my JS page because 'require' isn't available in the browser (I think that's what the issue is).
From where I stand now, I'm going to need to incorporate Node or I can rebuild the website as a React app and then install dotenv as a package and simply import it and the environment variable into my app.
I'd like to figure out the steps for adding it to my static HTML/CSS/JS site, if possible - but I'm not sure how to or even really how to phrase the question when I try to look it up.
Any guidance or insights appreciated!
P.S. Did you know I have a podcast with new episodes each Wednesday? Go listen right over here >>
Top comments (14)
You're on the right track here. If you don't want to expose your API key to the browser this is the way to go. You should even fetch your podcast data in the server to eliminate the need for your api key in the front-end.
This is fine too, but a bit of an overkill. You don't need react for this, just a bundler. I suggest using parcel because is the most easy to use. The downside of this is that it makes the "deploy process" more complex, unless of course you just push the bundled assets directly in github (Is what I would do [but I'm not a good role model]).
Once you finish setting up parcel you should create a
.env
file in the same directory you have thepackage.json
file.Then in your html or js files you can access the variables using the
process.env.
prefix. Like this.If your api keys or env variables are sensitive, this is not acceptable, as the compiled code that will be sent to the client will include the api keys or env bars as plain text.
Underneath the hood, webpack or parcel is doing a simple text replace
If you're still facing this problem, Github has a way for you to store secret or environment variables. If your goals is to hit the podcast API and save the JSON response in your project, you can use a Github action that does that: it will hit the API, gets the JSON response, put that JSON into a specific file or folder of your choosing in your project, then update your repository. I have one that does exactly that, except I hit an Airtable API for some spreadsheet info. Contact me if you want any help with it.
Thanks Dan, I'll definitely look in to this. Appreciate it!
This is totally doable via Github Actions, and Github gives you a way to have secrets or environment variables accessible via the Action. I have one that calls Airtable twice daily using the API key, pulls the json into the repo and rebuilds the website with the updated information. Totally viable and can be set to run on a schedule so you can set it and forget it!
There are some good answers here but I'll give a more old-school way this used to go down.
Your code would have something like ${env.api_key} in it.
Your build pipeline searches for those and replaces it with the correct value so your build artifact has the apikey built in, but what you check in does not.
I'm not sure the javascript way to facilitate that, but I'd be willing to bet someone already wrote something to do this.
I'm not 100% sure I understand, so bare with me.
You have an API key you want to use and you want that to be present in the javascript files that you serve to end users?
Yes! That's it. But I don't want the key to be able to be seen in the project files (on GitHub for example). Does that make sense?
Yes. 👍
I'm a bit out of the loop on web dev with APIs, but if you put the key in the JS file, doesn't that mean everyone who visits your website will have access to your API key (by reading the JS file)?
If that is the case, then to keep it only on your server you'll need some server side script to make the call to the API and then put the result into the site, either as the site is rendered or via fetch, XHR or similar.
I will admit I don't know react at all, and I don't know node.js very well, but it is used as a server side script runner, so it should have the capability to do the work you need.
Hey Alex,
Were you able to implement a solution for this? I am running into the same issue. I have a simple HTML, CSS, JS site that is using an API. I thought it would be easy to hide the API key but it has not been. I have considered just creating a react app as well, but would rather keep it simple.
Hi Skyler, just seeing this! I don't think I ever found a solution when I was working on this specific project. But know what I know now, I think you can do this easily via wherever you're deploying/hosting your app.
For example, Vercel makes it super easy to set hidden env variables.
vercel.com/docs/concepts/projects/...
Hope this helps!!
Static websites don't need ENV, but answering the question: You use Webserver ENV or system ENV.
Thanks, I'll try looking into that!
Webpack Define Plugin.
But then, anything to goes the frontend isn't secret. You had better use a server, or a serverless functions.