Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

RichText component reference

Use the RichText component to render Optimizely CMS content in React with full customization, type safety, and React-compatible attribute handling.

The RichText component is a React component that renders Optimizely CMS rich text content. It converts structured JSON content from the CMS into React elements and supports full customization.

📘

Note

Use the RichText component to render rich text content safely. It avoids dangerouslySetInnerHTML and allows custom React components for rendering elements.

Import RichText component

import { RichText } from '@optimizely/cms-sdk/react/richText';

Implement RichText component

import { RichText } from '@optimizely/cms-sdk/react/richText';

function Article({ content }) {
  return (
    <div>
      <RichText content={content.body?.json} />
    </div>
  );
}
🚧

Important

When rich text content is created through Optimizely's Integration API (REST API) rather than the CMS editor interface, certain features may not function correctly:

  • Inline styles - Some inline CSS properties might not work as expected. See Attribute and CSS Property Support for details on supported CSS properties.
  • HTML validation is bypassed, which can result in malformed or invalid HTML that causes rendering issues. Advanced formatting that relies on TinyMCE editor processing may be missing.
  • Custom attributes or props might not be mapped properly from raw HTML to React components.
  • Security sanitization performed by the editor may not occur.

For full feature compatibility and optimal rendering, create rich text content using the CMS's built-in TinyMCE editor interface.

Props Reference

content

Type: { type: 'richText', children: Node[] } | null | undefined

The rich text content from Optimizely CMS, typically accessed from a property of type richText.

<RichText content={article.body?.json} />

elements

Type: Record<string, React.ComponentType<ElementProps>>

Default: Built-in HTML element mappings.

Use this prop to customize how block and inline elements render.

Supported Element Types

  • Headings: heading-one –> heading-six.
  • Text blocks: paragraph, quote, div.
  • Lists: bulleted-list, numbered-list, list-item.
  • Inline text: span, strong, em, u, s, i, b, small, sub, sup, ins, del, kbd, abbr, cite, dfn, q, data, bdo, bdi.
  • Code: code, pre, var, samp.
  • Links & interactive: link, a, button, label.
  • Tables: table, thead, tbody, tfoot, caption, tr, th, td.
📘

Note

SVG elements are not supported by default. Use custom components or image assets for SVG content.

Example code snippet using Custom Elements

import { RichText, ElementProps } from '@optimizely/cms-sdk/react/richText';

// Custom heading with styling
const CustomHeading = ({ children, element }: ElementProps) => (
  <h1 className="text-4xl font-bold text-blue-600 mb-4">{children}</h1>
);

// Custom link with tracking
const CustomLink = ({ children, element }: ElementProps) => {
  const linkElement = element as LinkElement;

  return (
    <a
      href={linkElement.url}
      className="text-blue-500 hover:underline"
      onClick={() => trackLinkClick(linkElement.url)}
      target={linkElement.target}
      rel={linkElement.rel}
    >
      {children}
    </a>
  );
};

// Custom quote block
const CustomQuote = ({ children }: ElementProps) => (
  <blockquote className="border-l-4 border-gray-300 pl-4 py-2 italic text-gray-600">
    {children}
  </blockquote>
);

function Article({ content }) {
  return (
    <RichText
      content={content.body?.json}
      elements={{
        'heading-one': CustomHeading,
        link: CustomLink,
        quote: CustomQuote,
      }}
    />
  );
}

leafs

Type: Record<string, React.ComponentType<LeafProps>>

Default: Built-in text formatting mappings

Use this prop to customize text formatting marks.

Supported Leaf Types

  • bold, italic, underline, strikethrough, code

Example code snippet using Custom leafs

import { RichText, LeafProps } from '@optimizely/cms-sdk/react/richText';

// Custom bold with additional styling
const CustomBold = ({ children }: LeafProps) => (
  <strong className="font-extrabold text-gray-900">{children}</strong>
);

// Custom code with syntax highlighting theme
const CustomCode = ({ children }: LeafProps) => (
  <code className="bg-gray-100 px-1 py-0.5 rounded font-mono text-sm text-red-600">
    {children}
  </code>
);

// Custom highlight leaf (for custom mark)
const CustomHighlight = ({ children }: LeafProps) => (
  <mark className="bg-yellow-200 px-1 rounded">{children}</mark>
);

function Article({ content }) {
  return (
    <RichText
      content={content.body?.json}
      leafs={{
        bold: CustomBold,
        code: CustomCode,
        highlight: CustomHighlight, // Custom mark
      }}
    />
  );
}

decodeHtmlEntities

Type: boolean

Default: true

Controls whether HTML entities in text content should be decoded. When enabled, entities like &lt; , &gt; , &amp; are converted to their corresponding characters.

Example: Controlling HTML Entity Decoding

// Default behavior - entities are decoded
<RichText
  content={content.body?.json}
  decodeHtmlEntities={true} // &lt;div&gt; becomes <div>
/>

// Preserve HTML entities as-is
<RichText
  content={content.body?.json}
  decodeHtmlEntities={false} // &lt;div&gt; stays as &lt;div&gt;
/>

Use Cases for Disabling

// When displaying code examples where entities should remain encoded
const CodeExample = ({ content }) => (
  <div className="code-display">
    <RichText
      content={content}
      decodeHtmlEntities={false}
      elements={{
        paragraph: ({ children }) => <pre>{children}</pre>,
      }}
    />
  </div>
);

Complete Example

import React from 'react';
import {
  RichText,
  ElementProps,
  LeafProps,
} from '@optimizely/cms-sdk/react/richText';

// Custom element components
const CustomHeading = ({ children, element }: ElementProps) => (
  <h1 className="text-3xl font-bold mb-4 text-slate-800">{children}</h1>
);

const CustomParagraph = ({ children }: ElementProps) => (
  <p className="mb-4 text-slate-600 leading-relaxed">{children}</p>
);

const CustomLink = ({ children, element }: ElementProps) => {
  const link = element as { url: string; target?: string };
  return (
    <a
      href={link.url}
      target={link.target}
      className="text-blue-600 hover:text-blue-800 underline"
    >
      {children}
    </a>
  );
};

// Custom leaf components
const CustomBold = ({ children }: LeafProps) => (
  <strong className="font-semibold text-slate-900">{children}</strong>
);

const CustomItalic = ({ children }: LeafProps) => (
  <em className="italic text-slate-700">{children}</em>
);

const CustomCode = ({ children }: LeafProps) => (
  <code className="bg-slate-100 px-2 py-1 rounded text-sm font-mono text-slate-800">
    {children}
  </code>
);

export default function Article({ content }) {
  return (
    <article className="prose max-w-none">
      <RichText
        content={content.body?.json}
        elements={{
          'heading-one': CustomHeading,
          paragraph: CustomParagraph,
          link: CustomLink,
        }}
        leafs={{
          bold: CustomBold,
          italic: CustomItalic,
          code: CustomCode,
        }}
        decodeHtmlEntities={true}
      />
    </article>
  );
}

TypeScript Support

The component is fully typed with TypeScript. Import the prop types for better development experience:

import {
  RichText,
  RichTextProps,
  ElementProps,
  LeafProps,
  ElementMap,
  LeafMap,
} from '@optimizely/cms-sdk/react/richText';

// Type-safe element mapping
const elements: ElementMap = {
  'heading-one': CustomHeading,
  paragraph: CustomParagraph,
};

// Type-safe leaf mapping
const leafs: LeafMap = {
  bold: CustomBold,
  italic: CustomItalic,
};