Rendering Rich Text and Markdown | Yext Hitchhikers Platform

Yext Pages supports several ways to display formatted text based on what Knowledge Graph field type you use for rich text. As of @yext/pages-components v2.0.0, the library has been streamlined to prioritize the HTML subfield for Rich Text, providing a more stable and performant rendering experience.

The following list outlines the supported rendering methods for each Knowledge Graph field type as of @yext/pages-components v2.0.0:

  • Rich Text v2: Use the HTML subfield (required for @yext/pages-components v2.0.0+). The LexicalRichText component is supported only for legacy v1.x implementations.
  • Markdown: Use standard libraries like react-markdown.
  • Rich Text (Legacy): Support for the richTextDescription component is maintained only for legacy @yext/pages-components v1.x implementations.

Knowledge Graph: Create a Custom Field

As of the Summer ‘23 Release, we recommend using the Rich Text v2 or Markdown field types. The “Rich Text” (Legacy) field type is no longer supported. Refer to the Rich Text (v2) and Markdown Field Types reference doc for more information.

To utilize Rich Text v2 or Markdown, you must create a custom field.

Note: The platform does not allow you to change an existing field’s type. To move from Legacy Rich Text to Rich Text v2 or Markdown, you must create a new custom field and migrate your content. Follow the Migrate Legacy Rich Text Fields and Field Types guide for end-to-end instructions.

This is the standard method for all Pages implementations since the formatting is rendered directly by the Yext system. Starting with @yext/pages-components v2.0.0, this is the only supported way to render Rich Text v2.

Rich Text (v2) fields store a named sub-property for html. We recommend using this subfield because it ensures your frontend matches the Knowledge Graph editor exactly.

You can render the rich text using the dangerouslySetInnerHTML attribute:

<div dangerouslySetInnerHTML={{ __html: c_lrt.html }} />

where c_lrt is the custom field that uses the Rich Text (v2) field type.

Rendering Markdown

Markdown remains a flexible option for developers. While @yext/pages-components does not provide a dedicated wrapper component, you can easily render this content using industry-standard libraries.

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 Content

Whether you use the HTML subfield or Markdown, the output is standard HTML. 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).

Version 1.x Legacy Support

book
Note
Starting with pages-components version 2.0.0, the HTML subfield is the only supported method for rendering KG rich text. The components listed below have been removed in v2.0.0+.

(v1.x Only) Rich Text v2 - Lexical Rich Text Component

Note: Be sure to thoroughly QA your site. Since this component is built outside the Yext platform, changes to the component and to the Knowledge Graph field type may diverge.

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, use the LexicalRichText component:

import { LexicalRichText } from "@yext/pages-components";
<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.

Common Error:

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)

This occurs if you pass the raw field object instead of a stringified JSON. Ensure you use JSON.stringify([field].json).

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)} />

(v1.x Only) (Legacy) Rich Text Component

If you are using the Rich Text (Legacy) field type, the content is stored in a proprietary Markdown format.

For v1.x projects, we recommend using markdown-to-jsx .

import Markdown from 'markdown-to-jsx';
<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
The markdown-to-jsx component expects GitHub-flavored markdown. Because the Yext Rich Text (Legacy) field stores its own type of markdown, you may encounter rare rendering discrepancies.