I develop a Strapi local plugin but I'm unable to retrieve variable defined in my .env file at the root of my project. I try to load this value in my React component (plugins/myPluginName/admin/src/containers/HomePage/index.js).
I try with the global process module like that :
process.env.my_variable
But it returns undefined
Any ideas ?
Apparently, the admin panel now supports dotenv variables.
Just prefix your .env variable with STRAPI_ADMIN_ and it'll be available using process.env.
For example, STRAPI_ADMIN_KEY in .env is available as process.env.STRAPI_ADMIN_KEY
Thanks #sunnyson on the strapi forum I found a solution. By default .env variables are not passed to the client-side. You need to customize webpack config.
To do so :
Create a folder /admin at the root of your project then create a admin.config.js.
module.exports = {
webpack: (config, webpack) => {
// Add your variable using the DefinePlugin function
config.plugins.push(
new webpack.DefinePlugin({
// ENVS that you want to use in frontend
CUSTOM_VARIABLES: {
variable1: JSON.stringify(process.env.variable1),
},
})
);
// Return the modified config
return config;
},
};
In your react component you can use your env variables like that :
class HomePage extends React.Component {
constructor(props) {
this.state = {
env: { CUSTOM_VARIABLES }
}
logEnv() {
console.log(this.state.env.variable1)
}
}
Related
I have .env file in the project root, and in my nuxt config I am using variables to configure ReCaptcha like this:
import dotenv from 'dotenv'
dotenv.config()
export default {
modules: [
['#nuxtjs/recaptcha', {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
size: 'compact'
}],
]
}
and in .env like this:
RECAPTCHA_SITE_KEY=6L....
but the application always failed with console log error:
ReCaptcha error: No key provided
When I hard-code ReCaptcha key directly like that: siteKey: 6L.... app start working, so I guess the problem is with reading .env props in nuxt.config
do you have any idea how to fix it?
EDIT:
I tried update my nuxt.config by #kissu recommendation and by example which I found here: https://www.npmjs.com/package/#nuxtjs/recaptcha
so there is new nuxt.config which also not working:
export default {
modules: [
'#nuxtjs/recaptcha',
],
publicRuntimeConfig: {
recaptcha: {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
size: 'compact'
}
}
}
If your Nuxt version is 2.13 or above, you don't need to use #nuxtjs/dotenv or anything alike because it is already backed into the framework.
To use some variables, you need to have an .env file at the root of your project. This one should be ignored by git. You can then input some keys there like
PUBLIC_VARIABLE="https://my-cool-website.com"
PRIVATE_TOKEN="1234qwer"
In your nuxt.config.js, you have to input those into 2 objects, depending of your use case, either publicRuntimeConfig or privateRuntimeConfig:
export default {
publicRuntimeConfig: {
myPublicVariable: process.env.PUBLIC_VARIABLE,
},
privateRuntimeConfig: {
myPrivateToken: process.env.PRIVATE_TOKEN
}
}
Differences: publicRuntimeConfig can basically be used anywhere, while privateRuntimeConfig can only be used during SSR (a key can only stay private if not shipped to the browser).
A popular use case for the privateRuntimeConfig is to use it for nuxtServerInit or during the build process (either yarn build or yarn generate) to populate the app with headless CMS' API calls.
More info can be found on this blog post: https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config/
Then, you will be able to access it into any .vue file directly with
this.$config.myPublicVariable
You access it into Nuxt's /plugins too, with this syntax
export default ({ $axios, $config: { myPublicVariable } }) => {
$axios.defaults.baseURL = myPublicVariable
}
If you need this variable for a Nuxt module or in any key in your nuxt.config.js file, write it directly with
process.env.PRIVATE_TOKEN
Sometimes, the syntax may differ a bit, in this case refer to your Nuxt module documentation.
// for #nuxtjs/gtm
publicRuntimeConfig: {
gtm: {
id: process.env.GOOGLE_TAG_MANAGER_ID
}
},
PS: if you do use target: server (default value), you can yarn build and yarn start to deploy your app to production. Then, change any environment variables that you'd like and yarn start again. There will be no need for a rebuild. Hence the name RuntimeConfig!
Nuxt3 update
As mentioned here and in the docs, you can use the following for Nuxt3
nuxt.config.js
import { defineNuxtConfig } from 'nuxt3'
export default defineNuxtConfig({
runtimeConfig: {
public: {
secret: process.env.SECRET,
}
}
}
In any component
<script setup lang="ts">
const config = useRuntimeConfig()
config.secret
</script>
In a composable like /composables/test.js as shown in this comment
export default () => {
const config = useRuntimeConfig()
console.log(config.secret)
}
Here is the official doc for that part.
You can also use the env property with Nuxt
nuxt.config.js:
export default {
// Environment variables
env: {
myVariable: process.env.NUXT_ENV_MY_VAR
},
...
}
Then in your plugin:
const myVar = process.env.myVariable
It's very easy. Providing you an example with axios/nuxt
Define your variable in the .env file:
baseUrl=http://localhost:1337
Add the variable in the nuxt.config.js in an env-object (and use it in the axios config):
export default {env: {baseUrl: process.env.baseUrl},axios: {baseURL: process.env.baseUrl},}
Use the env variable in any file like so:
console.log(process.env.baseUrl)
Note that console.log(process.env) will output {} but console.log(process.env.baseUrl) will still output your value!
For nuxt3 rc11, in nuxt.conf.ts file:
export default defineNuxtConfig({
runtimeConfig: {
public: {
locale: {
defaultLocale: process.env.NUXT_I18N_LOCALE,
fallbackLocale: process.env.NUXT_I18N_FALLBACK_LOCALE,
}
}
},
...
and in .env file:
NUXT_I18N_LOCALE=tr
NUXT_I18N_FALLBACK_LOCALE=en
public: is very important otherwise it cannot read it and gives undefined error.
For v3 there is a precise description in the official docs
You define a runtimeConfig entry in your nuxt.config.[ts,js] which works as initial / default value:
export default defineNuxtConfig({
runtimeConfig: {
recaptchaSiteKey: 'default value' // This key is "private" and will only be available within server-side
}
}
You can also use env vars to init the runtimeConfig but its written static after build.
But you can override the value at runtime by using the following env var:
NUXT_RECAPTCHA_SITE_KEY=SOMETHING DYNAMIC
If you need to use the config on client-side, you need to use the public property.
export default defineNuxtConfig({
runtimeConfig: {
public: {
recaptchaSiteKey: 'default value' // will be also exposed to the client-side
}
}
}
Notice the PUBLIC part in the env var:
NUXT_PUBLIC_RECAPTCHA_SITE_KEY=SOMETHING DYNAMIC
This is very strange because we can't access process.env in Nuxt 3
In the Nuxt 3, we are invited to use the runtime config, but this is not always convenient, because the Nuxt application context is required.
But in a situation where we have some plain library, and we don’t want to wrap it in plugins nor composables functions, declaring global variables through vite / webpack is best:
// nuxt.config.ts
export default defineNuxtConfig({
vite: {
define: {
MY_API_URL: JSON.stringify(process.env.MY_API_URL)
}
}
})
And then you can use in any file without dancing with a tambourine:
// some-file.ts
console.log('global var:', MY_API_URL) // replaced by vite/webpack in real value
I want to load environment variables from the .env file using Vite
I used the import.meta.env object as mentioned in Docs
.env file:
TEST_VAR=123F
when trying to access this variable via the import.meta.env -> import.meta.env.TEST_VAR it returns undefined.
so, how can I access them?
According to the docs, you need to prefix your variables with VITE_:
To prevent accidentally leaking env variables to the client, only
variables prefixed with VITE_ are exposed to your Vite-processed code.
If you are trying to access env vars outside your app source code (such as inside vite.config.js), then you have to use loadEnv():
import { defineConfig, loadEnv } from 'vite';
export default ({ mode }) => {
// Load app-level env vars to node-level env vars.
process.env = {...process.env, ...loadEnv(mode, process.cwd())};
return defineConfig({
// To access env vars here use process.env.TEST_VAR
});
}
For svelteKit
// vite.config.js
import { sveltekit } from '#sveltejs/kit/vite';
import { defineConfig, loadEnv } from 'vite';
/** #type {import('vite').UserConfig} */
export default ({ mode }) => {
// Extends 'process.env.*' with VITE_*-variables from '.env.(mode=production|development)'
process.env = {...process.env, ...loadEnv(mode, process.cwd())};
return defineConfig({
plugins: [sveltekit()]
});
};
if you want to access your env variable TEST_VAR you should prefix it with VITE_
try something like
VITE_TEST_VAR=123f
you can access it with
import.meta.env.VITE_TEST_VAR
Here are three mistakes/gotchas that tripped me up.
Ensure the .env files are in the root, not the src directory. The filename .env and/or .env.development will work when running locally.
Restart the local web server for the variables to appear: npm run dev
Prefix the variables with VITE_ (as already mentioned by Mahmoud and Wonkledge)
Another solution that worked for me is to manually call dotenv.config() inside the vite.config.js. That will load variables from .env (all of them!) into process.env:
import { defineConfig } from 'vite'
import dotenv from 'dotenv'
dotenv.config() // load env vars from .env
export default defineConfig({
define: {
__VALUE__: process.env.VALUE
},
//....
}
where .env file could be:
VALUE='My env var value'
As stated in docs, you can change the prefix by mdoify envPrefix.
Env variables starting with envPrefix will be exposed to your client source code via import.meta.env.
So changing it to TEST_ will also work.
export default defineConfig({
...
envPrefix: 'TEST_',
...
})
You can change this option whatever you want except for empty string('').
envPrefix should not be set as '', which will expose all your env variables and cause unexpected leaking of sensitive information. Vite will throw an error when detecting ''.
So overriding the dotenv config directly to remove prefix completely could be an inappropriate action as all fields written in env would send directly into the client.
I had the same issue and solved it by running
pnpm add dot-env
pnpm add -S dotenv-webpack.
Lastly I made sure that I added VITE_ before the name I had for my environment variable, that is from MAP_API_KEY to VITE_MAP_API_KEY.
I'm trying to make a Keycloak integration with Gatsby.
I'd love to use environment variables for the Keycloak configuration so that I can properly containerize the application. I'm facing an issue about gatsby-browser.js that doesn't get environment variables.
Here's my gatsby-browser.js:
import React from 'react'
import { node } from 'prop-types'
import Keycloak from 'keycloak-js'
import { KeycloakProvider } from '#react-keycloak/web'
import { Spinner } from 'design-react-kit'
require('dotenv').config({
path: `.env.development`
})
const keycloak = new Keycloak({
realm: process.env.KEYCLOAK_REALM,
url: process.env.KEYCLOAK_AUTH_URL,
clientId: process.env.KEYCLOAK_AUTH_CLIENT_ID
})
const Loading = () => {
return (
<div className="container">
<Spinner
active
double
small={false}
tag="span"
/>
</div>
)
}
const wrapRootElement = ({ element }) => {
return (
<KeycloakProvider
keycloak={keycloak}
initConfig={{
promiseType: 'native',
onLoad: 'check-sso',
silentCheckSsoRedirectUri:
window.location.origin + '/silent-check-sso.xhtml'
}}
LoadingComponent={<Loading />}
>
{element}
</KeycloakProvider>
)
}
wrapRootElement.propTypes = {
element: node
}
const _wrapRootElement = wrapRootElement
export { _wrapRootElement as wrapRootElement }
When I launch gatsby develop I get:
Generating development JavaScript bundle failed
Can't resolve 'fs' in '/home/gbiagini/Documents/work/appaltinnovativi/swg-service/node_modules/dotenv/lib'
If you're trying to use a package make sure that 'fs' is installed. If you're trying to use a local file make sure that the path is correct.
File: node_modules/dotenv/lib/main.js
failed Building development bundle - 13.100s
I don't get why the fs package should be an issue considering that I do the exact same process on gatsby-config.js and works flawlessly.
As you can see in Gatsby's documentation about Environment variables your client-side variables must be prefixed with GATSBY_ to make them available to the client.
Client-side JavaScript
For Project Env Vars that you want to access in
client-side browser JavaScript, you can define an environment config
file, .env.development and/or .env.production, in your root folder.
Depending on your active environment, the correct one will be found
and its values embedded as environment variables in the browser
JavaScript.
In addition to these Project Environment Variables defined in .env.*
files, you could also define OS Env Vars. OS Env Vars which are
prefixed with GATSBY_ will become available in browser JavaScript.
So, you will need to prefix your .env variables and update your code:
const keycloak = new Keycloak({
realm: process.env.GATSBY_KEYCLOAK_REALM,
url: process.env.GATSBY_KEYCLOAK_AUTH_URL,
clientId: process.env.GATSBY_KEYCLOAK_AUTH_CLIENT_ID
})
I need to import a .js file with config values to be used on my react app:
import config from './config'
These values are already added at webpack configuration:
new webpack.DefinePlugin({...config})
What I need is to import these values into jest.config.js:
globals: {
config: // Here config...
}
"I know that we can add these values manually, but I want to add them from this file to prevent the maintenance of all values instead".
Thanks!
https://jestjs.io/docs/en/configuration#globals-object
Note that, if you specify a global reference value (like an object or array) here, and some code mutates that value in the midst of running a test, that mutation will not be persisted across test runs for other test files. In addition the globals object must be json-serializable, so it can't be used to specify global functions.
here is a guide on adding globals to your jest config with basic usage below
import * as config from "path/to/config";
//...package.json || jest.config
"jest": {
"globals": {
...config
}
}
const config = {
this: 'is now global'
}
console.log({
jest: {
globals: {
...config
}
}
})
You can add it to the globals object and import the config as normal
Let's say I have 5 jsx files and each file uses some config parameter.
My index.js file imports all of these 5 jsx files.
Instead of having my config data spread accross 5 files, is there a way for my jsx files to get the data from a global JS object which has loaded the data from a config file?
I've seen some examples, but I've not been able to get them to work.
JS6 import function | Example using webpack
Assuming ES6:
config.js
export const myConfig = { importantData: '', apiUrl: '', ... };
Then:
jsxFileOne.js, jsxFileTwo.js, ...
import { myConfig } from 'config.js';
There are other ways to import & export things globally leveraging webpack, but this should get you started.
If your project is built using Webpack, consider using node-env-file.
Example config file snippets:
development.env
API_SERVER_URL=https://www.your-server.com
webpack.config.js
const envFile = require('node-env-file');
...
const appSettingsFile = isDevBuild ? '/settings/development.env' : '/settings/production.env';
try {
envFile(path.join(__dirname + appSettingsFile));
} catch (error) {
console.log("Failed to read env file!: " + __dirname + appSettingsFile);
}
...
plugins: [
new webpack.DefinePlugin({
"process.env": {
API_SERVER_URL: JSON.stringify(process.env.API_SERVER_URL)
}
})
...
]
Inside your js/jsx code, you can now access process.env.API_SERVER_URL variable which will contain the required value.
It seems dotenv package is more popular, you can try this out as well.
Very old problem, that nobody took the time to solve, until now. I leave this for future readers because this is a top search result for configuration in React.
I created wj-config to deal exactly with this. Be sure to pay close attention to the React notes as you will need to enable top-level awaits in webpack, either by ejecting or using the #craco/craco NPM package.
You may also read this blog post that explains its use.