fix(landing): resolve error-page crash on invalid /models and /integrations routes (#4243)

* fix(layout): use plain inline script for PublicEnvScript to set env before chunks eval on error pages

* fix(landing): handle runtime env race on error-page renders

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.

* improvement(landing): use emcn Loader in scoped loading.tsx, trim auth-client comment

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Waleed
2026-04-21 12:43:43 -07:00
committed by GitHub
co-authored by Claude Opus 4.7
parent 2456128fb7
commit 42ef2b1dbb
4 changed files with 37 additions and 1 deletions
@@ -0,0 +1,9 @@
import { Loader } from '@/components/emcn'
export default function IntegrationDetailLoading() {
return (
<div className='flex min-h-[60vh] items-center justify-center bg-[var(--landing-bg)]'>
<Loader animate className='h-6 w-6 text-[var(--landing-text-muted)]' />
</div>
)
}
@@ -0,0 +1,9 @@
import { Loader } from '@/components/emcn'
export default function ModelDetailLoading() {
return (
<div className='flex min-h-[60vh] items-center justify-center bg-[var(--landing-bg)]'>
<Loader animate className='h-6 w-6 text-[var(--landing-text-muted)]' />
</div>
)
}
@@ -0,0 +1,9 @@
import { Loader } from '@/components/emcn'
export default function ModelProviderLoading() {
return (
<div className='flex min-h-[60vh] items-center justify-center bg-[var(--landing-bg)]'>
<Loader animate className='h-6 w-6 text-[var(--landing-text-muted)]' />
</div>
)
}
+10 -1
View File
@@ -15,8 +15,17 @@ 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'
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(),