I am creating a vue3 application (created with Vite) that interacts with a smart contract written in Solidity and stored on Ropsten. Therefore I am using web3js to interact with my smart contracts and also web3.storage in order to store some images on IPFS. I have a .env file at the root of my project storing my API key for web3.storage :
VUE_APP_API_TOKEN=VALUE
VITE_API_TOKEN=VALUE
The problem is that apparently web3.storage expects the API token to be stored in process.env and I am unable to access the global process variable from my application. I am always getting an error Uncaught ReferenceError: process is not defined.
I think, this is linked to my usage of Vite instead of pure Vue3.
I tried to export process env in the vite.config.ts file with that code but it didn't work:
export default ({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd(), '') };
console.log(process.env.VITE_API_TOKEN) //Works fine: VALUE is logged
console.log(process.env.VUE_APP_API_TOKEN) //Works fine: VALUE is logged
return defineConfig({
plugins: [vue()]
});
}
How could I access the process variable from my vue files in order to get the values of my environment variable and make web3.storage work?
.env
VITE_WEB3_STORAGE_TOKEN="your_token"
SomeComponent.vue: (or any other file of your app, really):
console.log(import.meta.env.VITE_WEB3_STORAGE_TOKEN) // "your_token"
Note: as specified in vite documentation, only variables prefixed with VITE_ will be exposed:
To prevent accidentally leaking env variables to the client, only variables prefixed with VITE_ are exposed to your Vite-processed code.
If you're running the build script in CI you will need to make sure that you're creating / populating the relevant .env file before you run the build script.
Related
I have the following api-helper that sets the base API URI
import getConfig from 'next/config'
// URI for back end
const {publicRuntimeConfig} = getConfig()
const apiUri = publicRuntimeConfig.external_uri;
export {apiUri}
This is my next.config.js (removed other code for brevity)
module.exports = {
publicRuntimeConfig: {
// Will be available on both server and client
external_uri: process.env.NEXT_PUBLIC_TEST_URI,
},
};
On my machine, I've set the environment variable NEXT_PUBLIC_TEST_URI to a value. However, when I look at my API call on the client-side, it is still showing as undefined.
On the other hand, when I populate the environment variables using the .env files in my project folder, everything works as expected.
I understand there may be a need to use getServersideProps in my api-helper but I'm not sure how I can do it in a simple way just to initialize a variable. It would also be good to understand why it works with the .env files but not an actual environment variable on the server.
I need it to work with an actual environment variable on the server as my end objective is to be able to update this variable and restart the node service without needing to rebuild the app.
apply-platform
env-bundle
node_modules
node-client
I have a repo apply-platform that has env variables and node modules, in the node module there is another repo node-client.
When I try to access process.env variables inside node-client project I get following object as process.env
{
\"LANG\":\"en_US.UTF-8\",\"PATH\":\"/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin\",\"HOME\":\"/home/ubuntu\",\"LOGNAME\":\"ubuntu\",\"USER\":\"ubuntu\",\"SHELL\":\"/bin/bash\",\"PM2_USAGE\":\"CLI\",\"PM2_HOME\":\"/home/ubuntu/.pm2\",\"SILENT\":\"true\",\"env_production\":\"[object Object]\",\"instance_var\":\"NODE_APP_INSTANCE\",\"exec_mode\":\"cluster_mode\",\"env\":\"[object Object]\",\"treekill\":\"true\",\"autorestart\":\"true\",\"automation\":\"true\",\"pmx\":\"true\",\"vizion\":\"true\",\"merge_logs\":\"true\",\"cwd\":\"/srv/cbax-apply-platform/\",\"log_type\":\"json\",\"instances\":\"4\",\"name\":\"www\",\"node_args\":\"\",\"pm_exec_path\":\"/srv/cbax-apply-platform/server.js\",\"pm_cwd\":\"/srv/cbax-apply-platform\",\"exec_interpreter\":\"node\",\"pm_out_log_path\":\"/home/ubuntu/.pm2/logs/application.log\",\"pm_err_log_path\":\"/home/ubuntu/.pm2/logs/application.log\",\"pm_pid_path\":\"/home/ubuntu/.pm2/pids/www-13.pid\",\"km_link\":\"false\",\"vizion_running\":\"false\",\"NODE_APP_INSTANCE\":\"0\",\"PM2_JSON_PROCESSING\":\"true\",\"_\":\"/usr/bin/pm2\",\"XDG_DATA_DIRS\":\"/usr/local/share:/usr/share:/var/lib/snapd/desktop\",\"SHLVL\":\"1\",\"PWD\":\"/srv/cbax-apply-platform/\",\"PORT\":\"8080\",\"NODE_ENV\":\"test\",\"REGION\":\"USEastTest\",\"www\":\"{}\",\"status\":\"launching\",\"pm_uptime\":\"1629364026293\",\"axm_actions\":\"\",\"axm_monitor\":\"[object Object]\",\"axm_options\":\"[object Object]\",\"axm_dynamic\":\"[object Object]\",\"created_at\":\"1629364026181\",\"pm_id\":\"13\",\"restart_time\":\"10\",\"unstable_restarts\":\"0\",\"_pm2_version\":\"2.6.1\",\"versioning\":\"null\",\"node_version\":\"9.11.1\",\"exit_code\":\"0\"}
How can I access process.env variables inside the node-module (node-client)
I tried console.log(JSON.stringify(process.env.env)) it still gives me [object][object] as output;
I found this object comes from ecosystem.config.js file of apply-platform , so added these 2 variables and pushed it to the server, but when I console process.env i cant see these 2 variables in node-client
The Node injects the process.env global variable at runtime in our app to use, and it represents the state of the system environment of our app when it starts. So, for example, if the system has the PATH variable set, this will be accessible to you through the process.env.PATH variable you can use to check where binaries are located and make external calls to them if required.
When we write the code, we can never be sure where our app can be deployed. If we require the database in development, we spin up the instance of it, and we link to it via a connection string , something like 127.0.0.1:3306. However, when deploying it to the server in production, we might need to link it to the remote server, 32.22.2.1.
Accessing environment variables in Node.js is supported out of the box. When your Node.js process boots up, it will automatically provide access to all the existing environment variables by creating the env object as a property of the process global object.
Explicitly loading variables from the .env file.
npm install dotenv --save
Afterward, add the following line to the very top of your entry file (index.js or app.js).
require('dotenv').config();
There is a npm module that loads environment variables from .env files into process.env, called dotenv. In your case, you would use it like this:
const dotenv = require("dotenv")
dotenv.config({ path: "/path/to/.env/"})
You could then access the environment variables in Node.js like this:
process.env.MYVAR
If you don't want the variables specified in the .env file to mangle with other environment variables, you can also do this:
const buffer = Buffer.from("PORT=3000") //example
const env = dotenv.parse(buffer) // returns object -> { PORT: 3000 }
// env.PORT would return 3000
dotenv.parse accepts a buffer object and returns an object, instead of binding it to process.env. You could also use the fs module to read the contents of the .env file, and pass it to dotenv.parse.
To learn more, reference the npm page for dotenv: https://www.npmjs.com/package/dotenv
I have a netlify react app. which is connected to my github. I'm using emailjs for receiving the messages from whoever reaches to my app.
emailjs deals with three ids 'SERVICE_ID', 'TEMPLATE_ID' and 'USER_ID'. But I don't wanna use them openly in my component js file.
Driver Function
function sendEmail(e) {
e.preventDefault(); //This is important, i'm not sure why, but the email won't send without it
emailjs.sendForm(SERVICE_ID, TEMPLATE_ID, e.target, USER_ID)
.then((result) => {
window.location.reload() //This is if you still want the page to reload (since e.preventDefault() cancelled that behavior)
}, (error) => {
console.log(error.text);
});
}
I think you're referring to environment variables, in order to test that out locally it will vary per the stack you use for creating the app, if you use react create app you can create a .env file in the root of your project and populate the values
REACT_APP_SERVICE_ID ="your_value"
REACT_APP_TEMPLATE_ID ="your_value"
REACT_APP_USER_ID ="your_value"
Don't forget to exclude this file from git, to avoid pushing secrets in your repo. to do that add this to your .gitignore
.env
After that you can call the variables in your code using the process.env like this:
process.env.REACT_APP_SERVICE_ID
Now modify the code:
function sendEmail(e) {
// Your code
emailjs.sendForm(process.env.REACT_APP_SERVICE_ID, process.env.REACT_APP_TEMPLATE_ID, e.target, process.env.REACT_APP_USER_ID)
// your promise
}
To make that work in netlify you would have to add the variable in your netlify project, follow this section to do that: https://docs.netlify.com/configure-builds/environment-variables/#declare-variables
As you noted I added the prefix REACT_APP_, this is because react create app does this:
Note: You must create custom environment variables beginning with
REACT_APP_. Any other variables except NODE_ENV will be ignored to
avoid accidentally exposing a private key on the machine that could
have the same name. Changing any environment variables will require
you to restart the development server if it is running.
If you are using gatsby or nextjs the env variables naming convention might change so please be aware of that.
You can set env variables on netlify. Please have a check the below images.
Check Adding env variables to react app
You can create a .env in your root dir and add your keys, api end points,... inside of it.
I have a react component which in development will redirect to a localhost url but in production to a different url. In my backend I have the same situation and there i solved it with a package called dotenv. I was wondering how someone would do this in a react front-end.
export default withRouter(function Login(props) {
useEffect(() => {
if(localStorage.getItem('jwt')){
props.history.push('/dashboard');
}
})
const handleLogin = () => {
window.location.href = "http://localhost:8000/auth/google";
}
return (
<LoginView handleLogin={handleLogin}/>
)
})
You can use dotenv to add environment variables to react as well. During app deployment(in the build process) the environment variables must be replaced with the corresponding URLs (as this is the most frequently encountered use case in front-end applications). This can be done while configuring the build process.
Here is an example using Webpack https://medium.com/#trekinbami/using-environment-variables-in-react-6b0a99d83cf5
The whole idea here is to create a file (called just .env) filled with
your environment variables. To prevent people from finding out your
local database password is the same one you use for every single one
of your accounts on the internet , I urge you to add the .env file to
your .gitignore. Your front-end code will refer to the same
environment variable (process.env.API_URL) on both environments
(development/production), but because you defined different values in
your .env files, the compiled values will be different.
I would suggest having a separate .env file for the react app as it should not be accidentally served with the website.
Create React App has a module(built around the node dotenv module) you can use for adding custom environment variables
https://create-react-app.dev/docs/adding-custom-environment-variables/
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.
Its depend on how you are using react.
If you are using react-script, you can go will above solution(https://create-react-app.dev/docs/adding-custom-environment-variables/).
But if you are using webpack, try to use DotenvPlugin in place of dotenv module (https://webpack.js.org/plugins/environment-plugin/).
In my opinion, pls don't follow method 1 use in medium link, as env should not be push on git but package.json need to be done.
i had build react app web page
with custom environment variables
the problem is when i build the script
and change the .env variables no thing change in the website !
.env file :
REACT_APP_SITENAME=TheSiteName App
After building a react app all code is static and can't be changed. I think the only solution to send some dynamic data to your react app is to either create a special file per system you running your app on and load this directly inside the index.html or create the content of this file on the fly.
So when you're using create-react-app in public/index.html add something like this:
<head>
...
<script src="https://www.example.com/envconfig.js" type="text/javascript">
</script>
...
</head>
This file should contain the environmental config, e.g.:
window.globalConfig = {
siteName: "The Sitename App"
}
The file can also be created on the fly by PHP, Java or any other backend service. Just make sure to answer as valid Javascript.
And in your React app at index.js, App.js or anywhere you can access this variable as it is global:
const appConfig = window.globalConfig || { siteName: process.env.REACT_APP_SITENAME}
With this you've got an fallback to the static env config if globalConfig is not available, likely in development.
Now you can use appConfig in any way and provide it via redux, context or property to your components.
Last thing to mention, you have to make sure that the config-file is loaded before executing all the React code. So the file should be loaded before all the created React files.
Quote from the docs:
The environment variables are embedded during the build time.
It isn't possible to apply environment changes as runtime.
Reference
Here is an example of how to use the environment at runtime:
CodeSandbox
here is an idea:
add a json file (e.a. config.json) with your configuration to the "public" folder. That file will be in the root of the build:
{
"name": "value" }
in your React code, create a static class with the variable you want to configure:
class Config {
static name= "[default value overwritten by the config]"; }
somewhere high in the startup of your React application, read the json and set the static variable:
fetch("config.json") .then((r) => r.json()) .then((data) =>{
Config.name=data.name; })
now you can use that config anywhere you need it :
Config.name
Note that any configuration you make will be vulnerable for public eyes, since the file can be opened directly with a URL. Also note that when deleting that json file, everything will still work with the default value. You could implement some check that the file must exist.