Rendering Rich Text and Markdown | Yext Hitchhikers Platform

Yext Content offers three field types for rich text:

  1. Rich Text (v2)
  2. Markdown
  3. Rich Text (Legacy)

As of the Summer ‘23 Release, the official recommendation moving forward is to use Rich Text v2 or Markdown. The Rich Text field is considered legacy and will not have support moving forward. Refer to the Rich Text (v2) and Markdown Field Types reference doc for more information.

Content: Create a Custom Field

To utilize Rich Text v2 or Markdown, you must create a custom field. The platform does not allow you to change a field’s field type, so even if you currently have a rich text field you’ll need to create a net-new field. Then you’ll need to add content to the newly added field for the appropriate entities.

Follow the Migrate Legacy Rich Text Fields and Field Types guide for end-to-end instructions.

Rendering Each in your Frontend

Lexical Rich Text Component

If not already installed, run the following command to install @yext/pages-components :

npm i @yext/pages-components

The LexicalRichText component renders a read-only view of the Rich Text v2 field. Styling for the various types of Rich Text elements can be optionally provided. If not provided, Yext default styling will be applied.

To render content from the Rich Text v2 field, import the LexicalRichText component into your project:

import { LexicalRichText } from "@yext/pages-components";

Here is a simple example of the component:

<LexicalRichText serializedAST={JSON.stringify(c_richTextDescriptionV2.json)} />

Props

Prop Type Details
serializedAST string A JSON-serialized Lexical Dev AST.
nodeClassNames? EditorThemeClasses CSS Class names for the various Lexical Node types. Refer to Lexical Theming documentation.

Error Setting up Lexical Rich Text Field

Below is a common error you may run into:

TypeError: editorState.isEmpty is not a function
 at LexicalEditor.setEditorState (/Users/my-user/Documents/Github/my-repo/node_modules/lexical/Lexical.dev.js:10747:21)

Solution

You receive this error when trying to simply pass the component a field name. The component is expecting the value passed to the serializedAST prop to be stringified JSON. Make sure to use the JSON stringify function on the JSON subfield of the desired field.

For example, if you are using the lexical rich text component with a blog body field (c_blogBody), the component would look like:

<LexicalRichText serializedAST={JSON.stringify(c_blogBody.json)} />

Markdown Component

To render content from a Markdown field, we recommend utilizing the open source react-markdown library. To do so, follow the installation instructions from react-markdown.

Styling Your Rich Text and Markdown

If you are using TailwindCSS, you can leverage a plugin like @tailwindcss/typography in order to add typographic defaults to any vanilla HTML you don’t control (like HTML rendered from Rich Text v2 or Markdown).

Rendering (Legacy) Rich Text

If you need to render any content from the Rich Text (legacy) field on your frontend, we recommend using an npm package such as markdown-to-jsx .

To render content using the markdown-to-jsx Markdown component, utilize the following import:

import Markdown from 'markdown-to-jsx';

Here is a simple example of the component:

<Markdown>{richTextDescription}</Markdown>

Here is a more advanced example of the component, with overrides configured for specific HTML tags from the incoming content (refer to the markdown-to-jsx parsing options documentation).

{/* Renders text with overrides for any h1 tags */}
<Markdown
  options={{
    overrides: {
      h1: {
        component: MyParagraph,
        props: {
          className: 'foo',
        },
      },
    },
  }}
>
  {richTextDescription}
</Markdown>
book
Note
Note, the markdown-to-jsx component expects GitHub-flavored markdown. The Yext Rich Text (legacy) field stores its own type of markdown; as such, you may encounter rare scenarios where your content is not rendered exactly as expected.