Describe the problem
With the current method of defining environment variables, dynamic variables are not validated at build time. This is common and expected behavior across a wide variety of frameworks going back decades.
The new "explicit environment variables" has gone a different route, stating that variables must have a value at build time. The logic here seems to be that if a dynamic variable is used in a static capacity, it will need a value. This is not unintuitive -- what is the point of differentiating static and dynamic variables if dynamic variables will be treated just like static variables apart from inlining?
The official workaround is to dynamically make your variables optional just at build time, but this requires sometimes substantial extra code or that potentially undesired dependencies be installed.
Describe the proposed solution
Add a flag prender to EnvVarConfig that controls if variables are validated for prerendering, defaulting to true. Setting this flag to false would prevent a variable with value not known until deploy time from being built.
Alternatives considered
-
One solution could be writing your own optional validators that only take effect at build time. This seems very verbose and counter-intuitive.
import { defineEnvVars } from '@sveltejs/kit/hooks'
import { building } from '$app/env'
export const variables = defineEnvVars({
SECRET: /** @type {import("@sveltejs/kit").EnvVarConfig<string>} */ {
schema: building
? {
["~standard"]: {
version: 1,
vendor: "",
validate: (value) =>
typeof value === "string" ? { value } :
typeof value === "undefined" ? { value: "" } :
{ issues: [{ message: "Value was not string or undefined." }]}
},
}
: undefined,
},
})
-
Another solution would be to not use explicit environment variables for dynamic variables that may not be available at build time. "Don't use the feature" is not a good way to use the feature, though...
import { building } from '$app/env'
function runtimeOnly(fn){
if(building) return undefined
return fn()
}
const SECRET = runtimeOnly(() => process.env.SECRET)
-
Another solution would be to require schema validators, thus leading users to install libraries where the official workaround is less verbose. A pure-SvelteKit solution would still be desireable.
import { defineEnvVars } from '@sveltejs/kit/hooks'
import { building } from '$app/env'
import * as v from "valibot"
function runtimeOnly(schema, dummyValue){
if(building) return v.optional(schema, dummyValue)
return schema
}
const variables = defineEnvVars({
SECRET: { schema: runtimeOnly(v.string()) }
})
-
A fourth solution would be to provide a wrapper schema that does the above automatically.
import { defineEnvVars, runtimeOnlyEnvVar } from '@sveltejs/kit/hooks'
import * as v from "valibot"
const variables = defineEnvVars({
SECRET: { schema: runtimeOnlyEnvVar() },
OTHER: { schema: runtimeOnlyEnvVar(v.pipe(v.string(), v.url())) },
})
-
A fifth solution would be to change the default behavior to not validate dynamic variables at build time, and instead require users to use static variables instead.
-
Use dummy values. This is unfriendly to new developers on projects, who will see unexpected errors due to incorrect values that have not been overriden.
Some less serious alternatives:
- Commit your secrets to git so they're available in CI pipelines.
Importance
would make my life easier
Additional Information
No response
Describe the problem
With the current method of defining environment variables, dynamic variables are not validated at build time. This is common and expected behavior across a wide variety of frameworks going back decades.
The new "explicit environment variables" has gone a different route, stating that variables must have a value at build time. The logic here seems to be that if a dynamic variable is used in a static capacity, it will need a value. This is not unintuitive -- what is the point of differentiating static and dynamic variables if dynamic variables will be treated just like static variables apart from inlining?
The official workaround is to dynamically make your variables optional just at build time, but this requires sometimes substantial extra code or that potentially undesired dependencies be installed.
Describe the proposed solution
Add a flag
prenderto EnvVarConfig that controls if variables are validated for prerendering, defaulting totrue. Setting this flag tofalsewould prevent a variable with value not known until deploy time from being built.Alternatives considered
One solution could be writing your own optional validators that only take effect at build time. This seems very verbose and counter-intuitive.
Another solution would be to not use explicit environment variables for dynamic variables that may not be available at build time. "Don't use the feature" is not a good way to use the feature, though...
Another solution would be to require schema validators, thus leading users to install libraries where the official workaround is less verbose. A pure-SvelteKit solution would still be desireable.
A fourth solution would be to provide a wrapper schema that does the above automatically.
A fifth solution would be to change the default behavior to not validate dynamic variables at build time, and instead require users to use static variables instead.
Use dummy values. This is unfriendly to new developers on projects, who will see unexpected errors due to incorrect values that have not been overriden.
Some less serious alternatives:
Importance
would make my life easier
Additional Information
No response