-
Notifications
You must be signed in to change notification settings - Fork 314
Description
#1738 added this documentation:
image/docs/content/3.providers/ipx.md
Lines 28 to 40 in 5d983d8
| You can update the options for `ipx` at runtime by passing the appropriate environment variable. For example: | |
| ```ts [nuxt.config.ts] | |
| export default defineNuxtConfig({ | |
| runtimeConfig: { | |
| ipx: { | |
| baseURL: process.env.NUXT_IPX_BASE_URL || '/_ipx', | |
| alias: { | |
| someAlias: process.env.NUXT_IPX_ALIAS_SOME_ALIAS || '' | |
| }, | |
| http: { | |
| domains: process.env.NUXT_IPX_HTTP_DOMAINS, | |
| }, |
The example says "You can update the options at runtime by passing the appropriate environment variable." and then it shows the actual usage of environment variables, but this is build-time usage, not run-time.
This code is a misleading antipattern. It misleads a user that they can refer to process.env in nuxt.config.ts and this will effective in runtime, which is not so. Whatever references to process.env are there in defineNuxtConfig, they are resolved during build time, and then literally imprinted to the output code:
Lines 159 to 165 in 5d983d8
| // Add runtime options | |
| addTemplate({ | |
| filename: 'image-options.mjs', | |
| getContents() { | |
| return generateImageOptions(providers, imageOptions) | |
| }, | |
| }) |
While NUXT_IPX_HTTP_DOMAINS indeed has runtime effect on the server ipx configuration, it is not happening because of reference to process.env.NUXT_IPX_HTTP_DOMAINS in the code above. It is caused by useRuntimeConfig().ipx inside routes/_ipx.ts.
Then, contrary to what the documentation implies, it is not possible to provide the list of domains at runtime with an environment variable.
The list of domains in resolveImage is taken from ctx.options:
Lines 82 to 91 in 5d983d8
| // Externalize remote images if domain does not match with `domains` | |
| if (provider.validateDomains && hasProtocol(input)) { | |
| const inputHost = parseURL(input).host | |
| // Domains are normalized to hostname in module | |
| if (!ctx.options.domains.find(d => d === inputHost)) { | |
| return { | |
| url: input, | |
| } | |
| } | |
| } |
which is directly passed from image-options.mjs which is generated at build time and does not use the runtime config:
image/src/runtime/composables.ts
Lines 5 to 13 in 5d983d8
| import { imageOptions } from '#build/image-options.mjs' | |
| import { useNuxtApp, useRuntimeConfig } from '#imports' | |
| export const useImage = (event?: H3Event): $Img => { | |
| const config = useRuntimeConfig() | |
| const nuxtApp = useNuxtApp() | |
| return nuxtApp.$img as $Img || nuxtApp._img || (nuxtApp._img = createImage({ | |
| ...imageOptions, |
Luckily, the options object is exposed by useImage() and one can fiddle with it in a plugin:
export default defineNuxtPlugin(async () => {
// Make `<nuxt-img>` use runtime list of domains.
// This relies on the respective server plugin that injects the data into Nuxt payload.
useImage().options.domains = useNuxtApp().payload.imageDomains
})What I propose is:
- At the very least, update the documentation and remove misleading use of
process.envindefineNuxtConfig():
- domains: process.env.NUXT_IPX_HTTP_DOMAINS,
+ domains: [], // Set in run-time with NUXT_IPX_HTTP_DOMAINS- Actually add a way to provide runtime environment variables (make them public and thus accessible client-side).