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 (
);
}