RichTextRenderer
Renders Contentstack JSON RTE (Rich Text Editor) content as React components.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
json | { children?: JSONRTENode[] } | Yes | - | JSON RTE content from Contentstack |
...htmlProps | HTMLAttributes<HTMLDivElement> | No | - | Standard div HTML attributes |
Usage
import RichTextRenderer from '@/components/atoms/RichTextRenderer';
<RichTextRenderer
json={content.copy}
className="prose prose-invert"
/>Supported Node Types
| Type | Renders As |
|---|---|
doc | Fragment (wrapper) |
paragraph / p | <p> |
h1 | <h1> |
h2 | <h2> (with auto-generated ID) |
h3 | <h3> |
h4 | <h4> |
heading | <h1>-<h6> (based on level attr) |
ul / list | <ul> |
ol | <ol> |
li / list-item | <li> |
blockquote / block-quote | <blockquote> |
a / link | Next.js <Link> |
img / image | <MediaItem> component |
code | <CodeBlockWithCopy> (syntax-highlighted with copy button) |
mermaid | <MermaidDiagram> |
mermaid-line | Mermaid source line collected by parent mermaid node |
embed | <div className="embed"> |
reference | Link or MediaItem (based on display-type) |
table | <table> (fluid table-fixed layout, percentage colgroup from CMS widths, wrapper scroll fallback) |
tbody / thead | <tbody> / <thead> |
tr | <tr> |
th / td | <th> / <td> (with colspan/rowspan from redactor-attributes) |
Text Formatting
Text nodes support:
- Bold:
bold: true - Italic:
italic: true - Underline:
underline: true
Features
- Auto-generated IDs: H2 headings get IDs for anchor links
- Empty paragraph filtering: Removes empty paragraphs
- Stable keys: Uses original index for consistent hydration
- Link handling: Converts links to Next.js Link components
- Image handling: Uses MediaItem component for images
- Code blocks: Renders syntax-highlighted code with copy-to-clipboard functionality
- Mermaid diagrams: Converts
mermaidandmermaid-linenodes into Mermaid source text and renders token-themed SVG diagrams client-side - Tables: Semantic HTML with
table-layout: fixed, column widths as percentages of the RTE pixel ratios (so tables stay within the prose column), cell wrapping, and horizontal scroll only as a fallback for unbreakable content - Memoized: Uses
useMemofor performance
Notes
- Returns
nullif no children or all are filtered out - H2 headings automatically get IDs using
generateHeadingIdutility - Links use Next.js Link component with proper target/rel attributes
- Images are rendered using the MediaItem component
- Mermaid diagram lines are joined with newline characters to preserve the CMS-authored diagram structure
- Mermaid diagrams render lazily near the viewport to reduce upfront work on long pages
- Client-side component (uses React hooks)