From 0d439cffc138dffe4667a708ea3b75d6e549e25f Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Tue, 21 Apr 2026 11:48:13 -0700 Subject: [PATCH 1/3] fix(layout): use plain inline script for PublicEnvScript to set env before chunks eval on error pages --- apps/sim/app/layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sim/app/layout.tsx b/apps/sim/app/layout.tsx index 326a18a6f00..0b79c386d96 100644 --- a/apps/sim/app/layout.tsx +++ b/apps/sim/app/layout.tsx @@ -239,7 +239,7 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= )} - + {/* Google Tag Manager (noscript) — hosted only */} From 7dfbe69654f073764400ed65aa5022a508587545 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Tue, 21 Apr 2026 12:15:42 -0700 Subject: [PATCH 2/3] fix(landing): handle runtime env race on error-page renders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit React skips SSR on unhandled server errors and re-renders on the client (see vercel/next.js#63980, #82456). Root-layout scripts — including the runtime env script that populates window.__ENV — are inserted but not executed on that client re-render, so any client module that reads env at module evaluation crashes the render into a blank "Application error" overlay instead of rendering the styled 404. This replaces the earlier PublicEnvScript tweak with the architectural fix: - auth-client.ts: fall back to window.location.origin when getBaseUrl() throws on the client. Auth endpoints are same-origin, so this is the correct baseURL on the client. Server-side we still throw on genuine misconfig. - loading.tsx under /models/[provider], /models/[provider]/[model], and /integrations/[slug]: establishes a Suspense boundary below the root layout so a page-level notFound() no longer invalidates the layout's SSR output (the fix endorsed by Next.js maintainers in #63980). - layout.tsx: revert disableNextScript — the research showed this doesn't actually fix error-page renders. The real fix is above. --- .../(landing)/integrations/[slug]/loading.tsx | 3 +++ .../models/[provider]/[model]/loading.tsx | 3 +++ .../(landing)/models/[provider]/loading.tsx | 3 +++ apps/sim/app/layout.tsx | 2 +- apps/sim/lib/auth/auth-client.ts | 20 ++++++++++++++++++- 5 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 apps/sim/app/(landing)/integrations/[slug]/loading.tsx create mode 100644 apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx create mode 100644 apps/sim/app/(landing)/models/[provider]/loading.tsx diff --git a/apps/sim/app/(landing)/integrations/[slug]/loading.tsx b/apps/sim/app/(landing)/integrations/[slug]/loading.tsx new file mode 100644 index 00000000000..2314344e038 --- /dev/null +++ b/apps/sim/app/(landing)/integrations/[slug]/loading.tsx @@ -0,0 +1,3 @@ +export default function IntegrationDetailLoading() { + return
+} diff --git a/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx b/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx new file mode 100644 index 00000000000..3291b24788a --- /dev/null +++ b/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx @@ -0,0 +1,3 @@ +export default function ModelDetailLoading() { + return
+} diff --git a/apps/sim/app/(landing)/models/[provider]/loading.tsx b/apps/sim/app/(landing)/models/[provider]/loading.tsx new file mode 100644 index 00000000000..6dfeb98d0d2 --- /dev/null +++ b/apps/sim/app/(landing)/models/[provider]/loading.tsx @@ -0,0 +1,3 @@ +export default function ModelProviderLoading() { + return
+} diff --git a/apps/sim/app/layout.tsx b/apps/sim/app/layout.tsx index 0b79c386d96..326a18a6f00 100644 --- a/apps/sim/app/layout.tsx +++ b/apps/sim/app/layout.tsx @@ -239,7 +239,7 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= )} - + {/* Google Tag Manager (noscript) — hosted only */} diff --git a/apps/sim/lib/auth/auth-client.ts b/apps/sim/lib/auth/auth-client.ts index ac524617290..ac21776502c 100644 --- a/apps/sim/lib/auth/auth-client.ts +++ b/apps/sim/lib/auth/auth-client.ts @@ -15,8 +15,26 @@ import { isBillingEnabled, isOrganizationsEnabled } from '@/lib/core/config/feat import { getBaseUrl } from '@/lib/core/utils/urls' import { SessionContext, type SessionHookResult } from '@/app/_shell/providers/session-provider' +/** + * On Next.js error-page renders (``), scripts from the + * root layout — including the runtime env script that populates `window.__ENV` + * — are inserted but not executed by React (see vercel/next.js#63980, #82456). + * Calling `getBaseUrl()` here at module evaluation would then throw and cascade + * the error-page render into a blank "Application error" overlay. On the + * client, auth endpoints are same-origin, so `window.location.origin` is a + * correct fallback; server-side we still surface a genuine misconfig. + */ +function getAuthBaseUrl(): string { + try { + return getBaseUrl() + } catch (e) { + if (typeof window !== 'undefined') return window.location.origin + throw e + } +} + export const client = createAuthClient({ - baseURL: getBaseUrl(), + baseURL: getAuthBaseUrl(), plugins: [ adminClient(), emailOTPClient(), From 51b5ee94cfd80ecb562209e69c7e71dc24458add Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Tue, 21 Apr 2026 12:29:07 -0700 Subject: [PATCH 3/3] improvement(landing): use emcn Loader in scoped loading.tsx, trim auth-client comment Co-Authored-By: Claude Opus 4.7 --- apps/sim/app/(landing)/integrations/[slug]/loading.tsx | 8 +++++++- .../app/(landing)/models/[provider]/[model]/loading.tsx | 8 +++++++- apps/sim/app/(landing)/models/[provider]/loading.tsx | 8 +++++++- apps/sim/lib/auth/auth-client.ts | 9 --------- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/apps/sim/app/(landing)/integrations/[slug]/loading.tsx b/apps/sim/app/(landing)/integrations/[slug]/loading.tsx index 2314344e038..3ee348ad1fe 100644 --- a/apps/sim/app/(landing)/integrations/[slug]/loading.tsx +++ b/apps/sim/app/(landing)/integrations/[slug]/loading.tsx @@ -1,3 +1,9 @@ +import { Loader } from '@/components/emcn' + export default function IntegrationDetailLoading() { - return
+ return ( +
+ +
+ ) } diff --git a/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx b/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx index 3291b24788a..af530c8b60e 100644 --- a/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx +++ b/apps/sim/app/(landing)/models/[provider]/[model]/loading.tsx @@ -1,3 +1,9 @@ +import { Loader } from '@/components/emcn' + export default function ModelDetailLoading() { - return
+ return ( +
+ +
+ ) } diff --git a/apps/sim/app/(landing)/models/[provider]/loading.tsx b/apps/sim/app/(landing)/models/[provider]/loading.tsx index 6dfeb98d0d2..7738ad1ed18 100644 --- a/apps/sim/app/(landing)/models/[provider]/loading.tsx +++ b/apps/sim/app/(landing)/models/[provider]/loading.tsx @@ -1,3 +1,9 @@ +import { Loader } from '@/components/emcn' + export default function ModelProviderLoading() { - return
+ return ( +
+ +
+ ) } diff --git a/apps/sim/lib/auth/auth-client.ts b/apps/sim/lib/auth/auth-client.ts index ac21776502c..a0ce3585b00 100644 --- a/apps/sim/lib/auth/auth-client.ts +++ b/apps/sim/lib/auth/auth-client.ts @@ -15,15 +15,6 @@ import { isBillingEnabled, isOrganizationsEnabled } from '@/lib/core/config/feat import { getBaseUrl } from '@/lib/core/utils/urls' import { SessionContext, type SessionHookResult } from '@/app/_shell/providers/session-provider' -/** - * On Next.js error-page renders (``), scripts from the - * root layout — including the runtime env script that populates `window.__ENV` - * — are inserted but not executed by React (see vercel/next.js#63980, #82456). - * Calling `getBaseUrl()` here at module evaluation would then throw and cascade - * the error-page render into a blank "Application error" overlay. On the - * client, auth endpoints are same-origin, so `window.location.origin` is a - * correct fallback; server-side we still surface a genuine misconfig. - */ function getAuthBaseUrl(): string { try { return getBaseUrl()