mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(env): restore beforeInteractive on the hosted public env script (#6214)
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
This commit is contained in:
@@ -26,14 +26,18 @@ function hasHttpProtocol(url: string): boolean {
|
||||
|
||||
function getBaseUrlImpl(): string {
|
||||
const baseUrl = readEnv('NEXT_PUBLIC_APP_URL')?.trim()
|
||||
if (!baseUrl) {
|
||||
throw new Error(
|
||||
'NEXT_PUBLIC_APP_URL must be configured for webhooks and callbacks to work correctly'
|
||||
)
|
||||
if (baseUrl) {
|
||||
// Mirrors the real module: protocol-less values get https:// under isProd.
|
||||
const protocol = envFlagsMock.isProd ? 'https://' : 'http://'
|
||||
return hasHttpProtocol(baseUrl) ? baseUrl : `${protocol}${baseUrl}`
|
||||
}
|
||||
// Mirrors the real module: protocol-less values get https:// under isProd.
|
||||
const protocol = envFlagsMock.isProd ? 'https://' : 'http://'
|
||||
return hasHttpProtocol(baseUrl) ? baseUrl : `${protocol}${baseUrl}`
|
||||
// Mirrors the real module: the browser falls back to its own origin, only
|
||||
// server-side (no `window`) callers throw.
|
||||
const browserOrigin = getBrowserOriginImpl()
|
||||
if (browserOrigin) return browserOrigin
|
||||
throw new Error(
|
||||
'NEXT_PUBLIC_APP_URL must be configured for webhooks and callbacks to work correctly'
|
||||
)
|
||||
}
|
||||
|
||||
function getInternalApiBaseUrlImpl(): string {
|
||||
|
||||
Reference in New Issue
Block a user