nitro
nitro copied to clipboard
`useRuntimeConfig` does not inherits env variables without passing `env` param in cloudflare workers
Ref: https://github.com/nuxt/nuxt/issues/25047
In the cloudflare workers runtime, the useRuntimeConfig utility without passing explicit (event) parameter fallsback to the ambient context's value which because of cf limitation of env passed to first request, is not extended from env. (src)
Ideally event context should default to useEvent() however ironically CF is one of the only presets that does not have LocalAsyncStorage support out of the box.
To make DX better and consistent for CF users, we can reevaluate _sharedRuntimeConfig value after first request to make sure useRuntimeConfig() will be upgraded at least once.
Other alternative would be to disable caching for _sharedRuntimeConfig value at all. This has benefit of having synchronized runtime config even when running in ambient context but downside of less performance. (I will probably do this as is more straight forward and covering)
useRuntimeConfig(event) does not work at the moment in CF, nor does import.meta.env.NUXT_VAR, only process.env.NUXT_VAR.
I think @atinux also is experiencing this. Not sure if this is the same bug as here or if we should raise a new one, but it seems like a new regression.
cc: @pi0
@danielroe i appreciate reproduction + new issue to investigate 🙏🏼
@pi0 @danielroe here is a great reproduction and overall test for envs on Cloudflare:
- https://github.com/Atinux/nuxt-env-repro
But from what I see and test, it works as it should. Either I'm missing information or it was a temporary problem with Cloudflare.
I also checked my production applications and it works fine.
I am using nitropack 2.9.6 and useRuntimeConfig() works fine without passing explicit (event). I think this one can be closed, as @oritwoen also reported it works fine?
However there is another issue that variables starting with NITRO_ are not passed automatically into runtimeConfig as expected: https://github.com/unjs/nitro/issues/2468
Could it possibly be a difference between using a node_compat environment? My test results say YES:
Update: my first comment did not consider that nodejs_compat automatically triggers v2 when compatibility_date is set to a date on or after 2024-09-23. Now, that is corrected.
Note, I did the tests inside a Nuxt3 project. But I assume this is the upstream issue to write this information.
Output from a deploy with compatibility_flags = ["nodejs_compat"] in the wrangler.toml:
Important: if you set nodejs_compat and a compatibility_date on or after 2024-09-23 it will automatically upgrade to nodejs_compat_v2 and thus trigger the output of the next example.
{
"runtimeConfig().hello": "config-defined-value", // this is the same value I defined in the nuxt.config.ts
"runtimeConfig(event).hello": "pages secret defined value", // this is the value I defined via wrangler pages secret put
"process.env.NUXT_HELLO": "pages secret defined value" // this is the value I defined via wrangler pages secret put
}
Output from a deploy with compatibility_flags = ["nodejs_compat_v2"] in the wrangler.toml:
This is the same for nodejs_compat_v2 and when you set nodejs_compat but also a compatibility_date on or after 2024-09-23.
{
"runtimeConfig().hello": "config-defined-value", // this is the same value I defined in the nuxt.config.ts
"runtimeConfig(event).hello": "config-defined-value" // this is the same value I defined in the nuxt.config.ts
}
Output from a deploy where I removed the ~~compatibility_flags = ["nodejs_compat_v2"]~~ in the wrangler.toml:
{
"runtimeConfig().hello": "config-defined-value", // this is the same value I defined in the nuxt.config.ts
"runtimeConfig(event).hello": "pages secret defined value", // this is the value I defined via wrangler pages secret put
"process.env.NUXT_HELLO": "pages secret defined value" // this is the value I defined via wrangler pages secret put
}
So, this result indicates that node_compat_v2 as of now (2025-02-28) is not supported when using the useRuntimeConfig(event) method. This would also explain why it works for some and not for others.
The two variants that got it working are:
- Do not use
nodejs_compatmode. - Use
nodejs_compatmode but with acompatibility_datethat is2024-09-22or before (because any date after that automatically triggersnodejs_compat_v2.
Working wrangler.toml:
compatibility_date = "2024-09-22"
compatibility_flags = ["nodejs_compat"]
Future work:
I hope someone with more "under-the-hood-knowledge" can look into this and get this supported for pages/workers with the node_compat modes.
@chrisspiegl Nitro 2.11 will natively support Cloudflare Node.js compatibility and you can remove
compatibility_flags for it altogether.
It is a complicated story. There are 2 definitions of "Node.js compact" in cloudflare (native support in cloudflare workers platforms and incompatible transforms wrangler or cloudflare pages used to add).
The reason for me to use the compatibility_flags is actually not nitro or nuxt but rather some crypto libraries I am using. Which leads to me needing it anyway. But the results of my tests show that the useRuntimeConfig() behaves in different ways depending on the nodejs_compat modes.
P.S. I tried installing the nitropack-nightly to do a deploy (to see if it would be able to read the useRuntimeConfig(event) stuff. But sadly with the same result as above (nodejs_compat + a recent compatibility_date breaks it).
Unfortunately crypto is a VERY bad idea on Cloudflare workers, at least with JS. I already got into that topic. BUT there is a solution, which is making another worker that runs Rust and your crypto library (argon2 I guess?). This other worker can be seamlessly connected to your existing JavaScript worker and be called from within your Nitro app.
Here is the package for the worker: https://github.com/glotlabs/argon2-cloudflare
I think this is called service binding, and you can call the Rust worker kinda like this:
await env.WORKER_B.fetch(request);
Not my use case for crypto, and I am using crypto-js. But in my experience, there are tones of reasons to use nodejs_compat and I'd hope that nitro can support this environment as well.
I just had a hunch on why this useRuntimeConfig(event) stuff is not available for some people and is working for others. I hope that this information helps in the development of nitro to bring support for nodejs_compat_v2 into the system.