docs: clarify functionality of $env/* variables#15078
docs: clarify functionality of $env/* variables#15078saibotsivad wants to merge 24 commits intosveltejs:mainfrom
$env/* variables#15078Conversation
Clarify the purpose and access restrictions of the module.
Clarified the description and usage of the $env/dynamic/public module, including details on public access and environment variable handling.
Clarify notes on environment variable handling in dev and prod.
|
|
Agreed that it took me a while and trying/testing to fully figure it out. It's a similar concept though (might even be) to Vite's environment variable mechanism. So, if Vite has a page that fully deep dives on it, maybe it's better to link to there as well? |
sveltekit add's to it, so it needs its own docs @saibotsivad This looks pretty good. Just a bit verbose. Idea for maintainers: Instead of 4 pages, we could combine them into one page |
|
Combining them all into a single page would definitely clean up some duplication in the docs. We would probably want to have redirects from e.g. I'm willing to rewrite to merge these docs, if maintainers think that's best, but I'd need coaching on how to do the redirects 😅 |
|
I was trying to figure out why the docs preview deploy isn't working, and finally figured it out -- the script expects your fork to also be named I'm trying to test this out locally instead, will get back to you as soon as I can |
|
I don't know if it's easier, but I can re-fork to |
|
Nah, I did the sensible thing and fixed the issue upstream. Merging |
elliott-with-the-longest-name-on-github
left a comment
There was a problem hiding this comment.
Sorry to send 29 comments, there are just some stylistic issues and some too-repetitive content. It looks good, though! Most of these suggestions you can probably just "add to batch" and commit at once, though the link ones you'll have to actually fix
| This module cannot be imported into client-side code. | ||
| | | Runtime | Buildtime | | ||
| | ------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | | ||
| | Private | `$env/dynamic/private` | [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private) | |
There was a problem hiding this comment.
| | Private | `$env/dynamic/private` | [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private) | | |
| | Private | [`$env/dynamic/private`](https://svelte.dev/docs/kit/$env-dynamic-private) | [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private) | |
There was a problem hiding this comment.
I know this is the current page but visually it's kind of confusing to have the others all be links and this one not
|
|
||
| **_Private_ access:** | ||
|
|
||
| - This module (and [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private)) cannot be imported into client-side code. |
There was a problem hiding this comment.
| - This module (and [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private)) cannot be imported into client-side code. | |
| - This module cannot be imported into client-side code |
| > MY_FEATURE_FLAG="enabled" npm run dev | ||
| > ``` | ||
|
|
||
| For example, suppose the runtime environment variables were set like this: |
There was a problem hiding this comment.
| For example, suppose the runtime environment variables were set like this: | |
| For example, given the following runtime environment: |
| PUBLIC_BASE_URL=http://site.com | ||
| ``` | ||
|
|
||
| If the `publicPrefix` is set to `PUBLIC_` and the `privatePrefix` is not set (the default behaviour): |
There was a problem hiding this comment.
| If the `publicPrefix` is set to `PUBLIC_` and the `privatePrefix` is not set (the default behaviour): | |
| With the default `publicPrefix` and `privatePrefix`: |
| | | Runtime | Buildtime | | ||
| | ------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | ||
| | Private | [`$env/dynamic/private`](https://svelte.dev/docs/kit/$env-dynamic-private) | [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private) | | ||
| | Public | `$env/dynamic/public` | [`$env/static/public`](https://svelte.dev/docs/kit/$env-static-public) | |
There was a problem hiding this comment.
Add the link here too (on all four pages)
| **_Public_ access:** | ||
|
|
||
| - This module (and [`$env/dynamic/public`](https://svelte.dev/docs/kit/$env-dynamic-public)) _can_ be imported into client-side code. | ||
| - **Only** variables that begin with [`config.kit.env.publicPrefix`](https://svelte.dev/docs/kit/configuration#env) (which defaults to `PUBLIC_`) are included. |
There was a problem hiding this comment.
| - **Only** variables that begin with [`config.kit.env.publicPrefix`](https://svelte.dev/docs/kit/configuration#env) (which defaults to `PUBLIC_`) are included. | |
| - **Only** variables that begin with [`config.kit.env.publicPrefix`](https://svelte.dev/docs/kit/configuration#env) (which defaults to `PUBLIC_`) are included |
| - This module (and [`$env/dynamic/public`](https://svelte.dev/docs/kit/$env-dynamic-public)) _can_ be imported into client-side code. | ||
| - **Only** variables that begin with [`config.kit.env.publicPrefix`](https://svelte.dev/docs/kit/configuration#env) (which defaults to `PUBLIC_`) are included. | ||
|
|
||
| For example, suppose the environment variables were set like this during build: |
There was a problem hiding this comment.
| For example, suppose the environment variables were set like this during build: | |
| For example, given the following buildtime environment: |
| PUBLIC_BASE_URL=http://site.com | ||
| ``` | ||
|
|
||
| Assuming the `publicPrefix` is set to `PUBLIC_` and the `privatePrefix` is not set (the default behaviour), this is what would happen at runtime, even if the environment variables at runtime are different: |
There was a problem hiding this comment.
| Assuming the `publicPrefix` is set to `PUBLIC_` and the `privatePrefix` is not set (the default behaviour), this is what would happen at runtime, even if the environment variables at runtime are different: | |
| With the default `publicPrefix` and `privatePrefix`: |
| import { PUBLIC_BASE_URL } from '$env/static/public'; | ||
| import { ENVIRONMENT, PUBLIC_BASE_URL } from '$env/static/public'; | ||
|
|
||
| console.log(ENVIRONMENT); // => undefined, throws error during build |
There was a problem hiding this comment.
| console.log(ENVIRONMENT); // => undefined, throws error during build | |
| console.log(ENVIRONMENT); // => throws error during build |
|
|
||
| console.log(ENVIRONMENT); // => undefined, throws error during build | ||
| console.log(PUBLIC_BASE_URL); // => "http://site.com" | ||
| ``` |
There was a problem hiding this comment.
| ``` | |
| ``` | |
| The above values will be the same _even if_ different values for `ENVIRONMENT` or `PUBLIC_BASE_URL` are set at runtime, as they are statically replaced in your code with their build-time values. |
I spent a lot of time trying to understand the `$env/* variables and how they behave, the docs didn't really seem very fleshed out and I was confused. I wrote up a bunch of demo code to make sure I really understood the behaviour, and then realized that a little love in the docs would probably be appreciated.
All sample code has been run locally and validated as correct as of
svelte@5.45.6(using thenpx sv createto make a minimal app). Anything that required validation between dev and prod I rannpm run build, editing the.envfile as necessary, and thennpm run previewto run.The overall idea
Here's how I broke it down conceptually:
$env/dynamic/private$env/static/private$env/dynamic/public$env/static/publicPrivate versus public:
publicPrefix/privatePrefix.Runtime versus buildtime:
Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
[ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs[ ] Ideally, include a test that fails without this PR but passes with it.Tests
[ ] Run the tests withpnpm testand lint the project withpnpm lintandpnpm checkChangesets
[ ] If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by runningpnpm changesetand following the prompts. Changesets that add features should beminorand those that fix bugs should bepatch. Please prefix changeset messages withfeat:,fix:, orchore:.Edits