Allow `PUBLIC_*` environment variables in `adapter-node` configuration
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the problem
The Node.js adapter natively supports special environment variables for configuring the runtime behavior of the Node.js server. Unfortunately, only the non-PUBLIC_*-prefixed versions of these environment variables are supported.
Why would this be useful?
Consider the ORIGIN environment variable, which is the source of truth for the base of the request URL. There are many cases when this ORIGIN would be useful to embed into the page.[^1].
[^1]: The data-login_uri for a "sign in with Google" button is my motivating example at work. You can also think about OpenGraph use cases with the <meta> tag.
Sadly, that can't be done out of the box because ORIGIN is a private environment variable, which requires being executed in a server context. Importing ORIGIN from a component results in a bundle error about leaking private variables to client-side code.[^2]
[^2]: This is great, by the way! 🎉
The correct way to expose this is to use PUBLIC_ORIGIN instead. But again, that doesn't work because adapter-node only checks for ORIGIN.
Describe the proposed solution
The env.js logic in adapter-node should be updated to also consider PUBLIC_*-prefixed environment variables in addition to the envPrefix.
Perhaps an open question would be: how should envPrefix interact with the PUBLIC_* prefix?
I say that the intuitive behavior is to check for both PUBLIC_{envPrefix}_* and {envPrefix}_* variables, but there is an argument to be made for {envPrefix}_PUBLIC_* instead. Personally though, I much prefer the former as it is more consistent with SvelteKit's existing rules on environment variables.
Alternatives considered
I've tried three workarounds for now and only one of them works closest to what I want.
- Setting
envPrefixtoPUBLIC. This works, but it exposes all of theadapter-nodeenvironment variables. If onlyPUBLIC_ORIGINis needed, this is quite overkill. - Proxying via the
loadfunction in+page.server.jsfiles. This also works, but it falls short when pre-rendering is enabled because it emits adata.jsonendpoint in the build output. It would certainly be unused as the page is pre-rendered, but I'd rather have it not emit anything at all. - Using
page.url.originin client-side code. This has been the best option so far. It still isn't perfect, though, because it now requires JavaScript execution just to obtain theoriginat runtime. The pre-rendered output results inhttp://sveltekit-prerenderbeing the substitute value.[^3] Ideally, this should be thePUBLIC_ORIGINitself.
[^3]: For OpenGraph use cases in <meta> tags, the origin being pre-rendered as http://sveltekit-prerender is a pre-render-exclusive SEO footgun because some web crawlers can't execute JavaScript.
Importance
nice to have
Additional Information
I'd be willing to submit a PR for this if the work is approved by the team. 🚀
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/adapter-node/src/env.js, especially the environment-variable handling at lines 4–17. Trace how envPrefix is applied and decide how PUBLIC_* variables should interact with it, including the competing prefix orders described in the issue. Done means the adapter recognizes the intended PUBLIC_* variables without exposing unrelated adapter settings.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100