How to hide an API key on a HTML page

Hi there,
I am working on my first static site (just a simple HTML page with vanilla JS) and I plan to deploy it to Netlify (not there yet).

Now, I have to make an API call to fetch some weather information using the OpenWeather API and then and display it on the page. For security reasons, I’d rather not hardcode my API key in the JS file (in this specific case I could even consider exposing the key but since I’m using this project as a learning experience, I’m trying to follow best practices).

At its core, my JS looks like

document.addEventListener('DOMContentLoaded', () => {
  const url = "";

  .then(response => response.json())
  .then(data => document.querySelector('#weather').innerText = JSON.stringify(data));

How could I achieve that?
I suppose one option could be to move the JS code in a lambda function. However, I have googled for some samples but I haven’t found any example that updates the DOM from a lambda function. Would that be possible?

Alternatively, can I access for my JS the ENV variables defined from the Netlify UI?

Is there any other option not to hardcode my API key?

Thank you for the help.

You don’t need to have the function update the DOM (which is indeed not possible), you just need to have it return the data you need.

So your function could look like this:

const apiKey = process.env.API_KEY;

exports.handler = async (event) => {
  const url = `${apiKey}`;

  const response = await fetch(url);
  const data = await response.json();

  return {
    statusCode: 200,
    body: JSON.stringify({
      data: data

You can then fetch the function and use the data to manipulate the DOM once it loads. (EDIT: like @hrishikesh just posted :partying_face:)

1 Like

You can’t update DOM from Functions. You can just receive JSON data.

What you can do it, use a HTTP fetch in a Function:

const url = "" + process.env.API_KEY

where API_KEY is an environment variable set in the UI.

The you would have to return the data and in your app’s JavaScript you can use like:

fetch('/.netlify/functions/getWeather').then(response => reponse.json()).then(data => {
  // data holds your JSON data and update the DOM in this function
}).catch(error => {
// handle the error here
1 Like