Skip to main content
Our new developer certification is live!

ComponentsRenderer

System component that dynamically renders Contentstack components based on their type.

Props

PropTypeRequiredDefaultDescription
components(HeroComponents | ComponentsPage | TwoColumnSide)[]Yes-Array of component objects
cslpCSLPFieldMappingNo-CSLP mapping for editable fields
cslpWrapperstringNo-CSLP wrapper identifier
priorityFirstMediabooleanNofalseMarks the first media component as priority for faster LCP
mediaSizesstringNo-Optional sizes string to pass to the prioritized media image
noPaddingbooleanNofalsePasses noPadding to child components to remove section padding

Supported Components

Component NameComponentDescription
heroHeroHero section with title, CTAs, and nested components
listListGrid of cards (DefaultCard or IconCard)
mediaMediaImage/media display
rich_textRichTextRich text content with optional title
two_columnTwoColumnTwo-column layout with nested components
noticeNoticeAlert/notice box with variants

Usage

import { ComponentsRenderer } from '@/components/system/ComponentsRenderer';

<ComponentsRenderer
  components={[
    { hero: { title: "Welcome", ... } },
    { list: { title: "Features", cards: [...], ... } },
    { rich_text: { title: "About", copy: {...} } },
    { two_column: { side_a: [...], side_b: [...] } },
    { notice: { title: "Note", type: "notice", ... } }
  ]}
  cslp={cslpData}
  cslpWrapper="components"
/>

Features

  • Dynamic rendering: Renders components based on type using a componentMap lookup
  • Type safety: Type-safe component mapping with TypeScript
  • CSLP support: Wraps components with CSLP attributes in preview mode
  • Error handling: Shows error message for unknown component types
  • Empty state: Shows empty block in preview mode if no components
  • Above-the-fold media priority: When priorityFirstMedia is true, injects priority: true into the first media component for faster LCP
  • Above-the-fold list priority: Automatically detects list components at index 0 or 1 and injects priorityFirstImage: true so the first card image loads eagerly

Component Mapping

Components are mapped from Contentstack format:

[{ "hero": { ...props } }]

To internal format:

{ name: "hero", props: { ...props } }

Image Priority Logic

The renderer applies two automatic image priority optimizations:

  1. Media priority (priorityFirstMedia): When enabled (e.g., inside Hero), the first media component gets priority: true and a custom sizes attribute. This is opt-in via props.

  2. List priority (automatic): When a list component appears at index 0 or 1 in the components array (above the fold), it automatically receives priorityFirstImage: true, which makes the first card's image load with fetchPriority="high" and loading="eager".

Notes

  • Uses componentMap for type-safe rendering
  • Generates keys from component UID or index
  • Shows red error box in development for unknown components
  • Wraps components with CSLP divs in preview mode
  • Used by Page, Hero, and TwoColumn to render their component arrays