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.
kit/packages/adapter-node/src/env.js
Lines 4 to 17 in 293392b
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.
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
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
envPrefix
toPUBLIC
. This works, but it exposes all of theadapter-node
environment variables. If onlyPUBLIC_ORIGIN
is needed, this is quite overkill. - Proxying via the
load
function in+page.server.js
files. This also works, but it falls short when pre-rendering is enabled because it emits adata.json
endpoint 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.origin
in 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 theorigin
at runtime. The pre-rendered output results inhttp://sveltekit-prerender
being the substitute value.3 Ideally, this should be thePUBLIC_ORIGIN
itself.
Importance
nice to have
Additional Information
I'd be willing to submit a PR for this if the work is approved by the team. 🚀
Footnotes
-
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. ↩ -
This is great, by the way! 🎉 ↩
-
For OpenGraph use cases in
<meta>
tags, the origin being pre-rendered ashttp://sveltekit-prerender
is a pre-render-exclusive SEO footgun because some web crawlers can't execute JavaScript. ↩