Environment Variables

I have tried looking through as many resources as possible but I cannot get it to work. I set up a way to send emails with emailjs, and I even did this in a very similar way for a different site a couple weeks ago. However, when I set up the environment variables, they are always undefined, even when it is very clear that I have set them up.

Here is where I am doing the call with the env

emailjs.send(
process.env.REACT_APP_SERVICE_ID,
“template_sq70hbr”,
{
name: formData.name,
city: formData.city,
state: formData.state,
homePhone: formData.homePhone,
cellPhone: formData.cellPhone,
email: formData.email,
},
process.env.REACT_APP_PUBLIC_KEY
);

They are defined clearly here. And I tried importing from a .env file which also failed to change the results.

This is the error I get. However when testing locally without the .env but rather with the strings themselves, it works perfectly well.
image

I also tried declaring them in the build command (replaced the actual variables with *)
REACT_APP_SERVICE_ID = * REACT_APP_PUBLIC_KEY = * npm run build

I created the app with vite if that changes anything. Please let me know if there is anything else I can try. Thank you

Can you share the link for your site.

https://inspiring-figolla-f4d44c.netlify.app/

Indeed, I see REACT_APP_SERVICE_ID and REACT_APP_PUBLIC_KEY embedded in the code instead of the values of the variables. Do check out

If using Vite, you might also check out the Vite Env Variables documentation.

I would advise against doing what you currently are, as those private variables end up exposed which means anyone could potentially use your API KEY to send emails. Better to hide sensitive keys/tokens in a function. See

I have already looked through the first post, but I either misunderstood how to do it properly or it would throw errors. If I tried to add the variables as part of the build command, it would not let me. Also, correct me if I’m wrong, but I thought the point of using environment variables was so that I could use a variable in my client side code, but the actual values are stored in Netlify itself so that it wouldn’t be accessible. I was hoping that Netlify would act as the server protecting the API information. Am I mistaken?

From the second post it says

“If you just need a token during build, you can use our Environment Variables build settings to set a value for a $API_TOKEN environment variable, and reference it during build. Nearly all headless CMS’s use this pattern, for instance - Netlify knows how to access your data from Contentful or Sanity, and pulls it in during build. You may not need the token at browse time, and so it isn’t in your HTML output, and you’re safe!”

I am trying to do this, but does it need to be specifically named $API_TOKEN as the environment variable and then referenced through that? I am confused as to why I declared the environment variables inside of Netlify but can’t access them. I know they should be protected and that is what I am trying to do, but please let me know why it would not work the way I am trying if I am wrong

Yes, you are mistaken in this instance.

As the Create React App Adding Custom Environment Variables documentation states

The environment variables are embedded during the build time. Since Create React App produces a static HTML/CSS/JS bundle, it can’t possibly read them at runtime. To read them at runtime, you would need to load HTML into memory on the server and replace placeholders in runtime, as described here. Alternatively you can rebuild the app on the server anytime you change them.

The Vite documentation previously linked also states the same

During production, these env variables are statically replaced. It is therefore necessary to always reference them using the full static string. For example, dynamic key access like import.meta.env[key] will not work.

The second support guide linked above talks about using a function to make the API call and returning the data to the front-end. This way, the function is consuming the environment variables and they aren’t exposed to the front-end. This is the only way to keep them out of front-end code.

Thank you for clarifying