The hosted `<PublicEnvScript>` rendered a plain `<script>`, which lands at
the end of `<head>` — after the ~40 `<script async>` chunk tags Next emits
at the top of the document. An async script runs as soon as its fetch
resolves, so on a warm cache a Next chunk could execute (and hydration
begin) before the parser reached the env tag, leaving `window.__ENV`
undefined for the first render.
That surfaced as "Something went wrong" on the workflow page, since
`getBaseUrl()` throws during the deploy modal's render, and as the socket
falling back to the page origin instead of NEXT_PUBLIC_SOCKET_URL.
Regressed in #5522, which replaced next-runtime-env's PublicEnvScript
(to avoid its unstable_noStore forcing dynamic rendering) with a static
equivalent that dropped the beforeInteractive strategy.
- render the library's own `<EnvScript>`, which defaults to
beforeInteractive and does not call unstable_noStore — hosted and
self-hosted now share one implementation and one loading strategy
- drop the hand-rolled serialization and `<` escaping; Next's
beforeInteractive path already runs the payload through
htmlEscapeJsonString, which escapes `& > < U+2028 U+2029`
- fall back to the browser origin in getBaseUrl() rather than throwing,
so a missing injected env can never tear down a page through the error
boundary; server-side callers still fail loudly
- read NEXT_PUBLIC_EMAIL_PASSWORD_SIGNUP_ENABLED via getEnv() in the SSO
form, matching login/signup/auth-modal — `env.X` returns the build-time
placeholder, not the runtime value