payload: Public PAYLOAD_PUBLIC environment variables don't work in production builds
Bug Report
I want to use a public environment variable for the S3 URL of my app. I have this in my .env file:
PAYLOAD_PUBLIC_S3_URL=https://my-bucket.s3.eu-central-1.amazonaws.com
…and this in my src/collections/Media.ts file:
adminThumbnail: ({ doc }) => {
let media = doc as unknown as MediaType;
return `${process.env.PAYLOAD_PUBLIC_S3_URL}${media.sizes.thumb.url}`;
},
Everything works great when I npm run dev. The served URLs in the panel are these:
https://my-bucket.s3.eu-central-1.amazonaws.com/media/my-image-350x233.jpg
But when I make a production build with npm run build and then open the app with npm run serve, I get these URLs:
undefined/media/my-image-350x233.jpg
When I search for my bucket URL in the resulting build folder, it’s nowhere to be found.
Other Details
Payload version 1.3.0
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 4
- Comments: 27 (24 by maintainers)
OK! So, you need to add the following at the top of your payload config file.
If you were fetching your env variables from a remote source you would need to wire up a custom build script that uses payloads build script after fetching your remote variables, something like this:
And you would use that in your build command instead of payload build 👍
@hdodov wow I never responded - my bad, I totally thought I did.
The reason it must be declared in both places is because:
I am not sure there is a single solution to allow for both to be done without declaring it in both.
@CallMeLaNN Yes I think that the example should be updated. I think we should add the import statements for dotenv in both places. Would you like to contribute with a simple PR to the 3
src/templates/[template-name]/src/payload.config.tsfiles? (see them here)examaple (blog template):
@CallMeLaNN What I mean by ‘changed at startup’ is when calling ‘yarn serve’, either locally or in a docker container, the values passed will be ignored and instead the values set in the .env file will be used.
@JarrodMFlesch I’m doing this in
server.ts:…and this in
payload.config.ts:…and it works alright. My main concern is this:
The user shouldn’t have to include dotenv in both places. That was my point - the docs I quoted suggest loading dotenv in
server.ts, but doing so (without also loading it inpayload.config.ts) won’t work.It’d be great DX if
PAYLOAD_PUBLICvariables can work without having to load dotenv twice.Thank you, @JarrodMFlesch. I tried this out, and it is working now. In case others in the future get hung up on this, I should specify that in order to get this to work, I added the following to the top of server.ts:
and this to the top of payload.config.ts:
@brachypelma can you try using import instead of using require statement? I do get the blank screen error when using require to import dotenv.
With this I am able to run dev and build, and read env vars in both. Let me know!
@JarrodMFlesch , than you for posting your solution to this problem. Unfortunately, I cannot get this to work. This may just be a misunderstanding on my part. Please let me know if it is.
My goal is to have separate .env files, one on my local computer for local development and one on my server for production use. I want to be able to have different serverURL and CORS config options in my payload.config for local and production development, so I would like to read these payload.config values from the .env files so the same config file will work in each environment.
Here is an example app I put together following your guidelines above.
https://github.com/brachypelma/payload-env-test
My steps to create this:
npx create-payload-appwith TS and blank template optionsPAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000When I save this and run
npm run devand then loadhttp://localhost:3000/adminin my browser, I get a blank screen and this in the console:Uncaught TypeError: dotenv__WEBPACK_IMPORTED_MODULE_2__.config is not a function ts payload.config.ts:7
I’m not sure why dotenv.config is not recognized as a function, especially since it is called in server.ts
FWIW, I tried removing the dotenv.config call from payload.config and added the specified option to the dotenv.config call in server.ts, i.e.:
However, when I do that, .env variables loaded in payload.config are undefined when I build the app.
Can you offer any help? I’m not really sure what I am doing wrong here. Apologies again if I just misunderstood your solution.