import type { ResolvedSection } from "@decocms/blocks/cms"; import { getSection, getSectionOptions, getSyncComponent } from "@decocms/blocks/cms"; import { SectionErrorBoundary } from "@decocms/blocks/hooks"; import { createElement, type ReactNode } from "react"; import { ClientOnlySection } from "./ClientOnlySection"; interface SectionRendererProps { resolved: ResolvedSection; errorFallback?: ReactNode; } /** * Renders one resolved section. Runs inside an async Server Component tree, * so code-split sections are loaded via a plain await — no client-side * React.lazy/Suspense needed for content in the initial response. */ export async function SectionRenderer({ resolved, errorFallback }: SectionRendererProps) { const sectionId = resolved.key .replace(/\//g, "-") .replace(/\.tsx$/, "") .replace(/^site-sections-/, ""); const options = getSectionOptions(resolved.component); const errFallback = options?.errorFallback ? createElement(options.errorFallback, { error: new Error("") }) : errorFallback; const isClientOnly = options?.clientOnly === true; const SyncComp = getSyncComponent(resolved.component); let content: ReactNode; if (isClientOnly) { const loader = getSection(resolved.component); if (!loader) { console.warn(`[SectionRenderer] No component registered for: ${resolved.component}`); return null; } content = ; } else if (SyncComp) { content = createElement(SyncComp, resolved.props); } else { const loader = getSection(resolved.component); if (!loader) { console.warn(`[SectionRenderer] No component registered for: ${resolved.component}`); return null; } const mod = await loader(); content = createElement(mod.default, resolved.props); } return (
{content}
); }