Rich text support

Rich text gives editors control over how text and other elements appear within a component. This could be as simple as allowing inline formatting in the form of bold and italic text effects, or more specialized elements such as block quotes, code blocks, or even images or tables.

rich-text-example
Example of the Uniform rich text editor UI

Most systems distill the formatting from rich text into a proprietary JSON format that's programmatically consumed by your chosen front end, converting the raw data into web-friendly HTML.

Rich text fields can vary dramatically in terms of their function and capabilities. Most systems supporting this formatting will also provide a proprietary package or rendering engine that does the heavy lifting so that rich text works seamlessly when computed into HTML.

An important early decision to make is if you want your editors to create and maintain rich text for a given component within Uniform directly or from an external system. Unlike many parameters in Uniform, the Rich Text parameter isn't designed to be connected to external data as Uniform can't guarantee that external sources utilise a compatible data structure to the one supported by Uniform's packages.

Out of the box you will find that Uniform supplies a parameter type called Rich Text that can be implemented on any component or content type. Once implemented, the parameter will allow you to enter and format rich text directly in compositions and entries.

Adding the Uniform Rich Text parameter is the same as adding any other parameter type. Navigate to the component definition which you would like to add a Rich Text property to and select Add parameter. Then select the Rich Text parameter type:

add-rich-text-parameter
Add the rich text parameter.

Once added, you will be able to control the formatting options that you would like to make available to your editors. This provides necessary governance to prevent authors from using elements that aren't part of the design system (such as block quotes).

rich-text-config
Configure the rich text parameter.

Once your new parameter has been saved, configuration is complete. Next, you will need to ensure that your front end is able to process the rich text field, converting it to web-friendly HTML.

Uniform stores any content that's entered into the Rich Text parameter in a JSON format delivered through Uniform's APIs and compiled into HTML. Below are some ways you can perform this compilation of HTML using the Uniform SDK.

Uniform provides a Vanilla.js-based rich text to HTML renderer as well as components for React and Vue. Each option allows for overriding the way a rich text node is rendered.

There are two types of React or Vue components:

  1. UniformRichText which is given a parameterId. It will look up the value based on a current component. This is likely to be the simplest way to render rich text fields within the application.

    Rich Text in Blocks

    Rich Text parameters nested within a block parameter are not currently supported by the UniformRichText component. Use the UniformRichTextNode component instead.

  2. The UniformRichTextNode component which can be given the node data directly.

Uniform also supplies framework-specific components for Next.js and Nuxt. These take care of overriding some nodes which have framework-specific functionality like the link node.

Next.js

If you are using Next.js, import the same component from the @uniformdev/canvas-next package to get enhancements based on the framework.

import { UniformRichText } from '@uniformdev/canvas-react' function MyComponent() { return ( <> <h1>My Uniform Component</h1> <UniformRichText parameterId="articleBody" // Rendered in preview mode when the parameter is empty placeholder="Rich Text goes here" /> </> ) }

Rich text content will look something like this:

const richTextNode = { root: { type: 'root', version: 1, children: [ { type: 'paragraph', version: 1, children: [ { type: 'text', version: 1, text: 'text', }, ], }, ], }, }
import { UniformRichTextNode } from '@uniformdev/canvas-react' function MyComponent() { const richTextNode = { ... } return ( <> <h1>Article</h1> <UniformRichTextNode node={richTextNode} /> </> ) }

Compared to simpler parameters, the Rich Text parameter value is a complex JSON object, so checking if it's empty can be more complicated than comparing the value to an empty string or undefined. To help with this task, the @uniformdev/richtext package exports an isRichTextValueConsideredEmpty function that you can use to check if the parameter is empty.

import { UniformRichText } from '@uniformdev/canvas-react' import { isRichTextValueConsideredEmpty } from '@uniformdev/richtext' function MyComponent({ articleBody}) { return ( <> <h1>My Uniform Component</h1> {isRichTextValueConsideredEmpty(articleBody) ? null : ( <div> <UniformRichText parameterId="articleBody" // Rendered in preview mode when the parameter is empty placeholder="Rich Text goes here" /> </div> )} </> ) }

You can override internal rich text node renderers:

import { UniformRichTextNode } from '@uniformdev/canvas-react' function MyParagraphRichTextNode({ node, children }) { return <p class="my-paragraph">{children}</p> } function resolveRichTextRenderer(node) { if (node.type === 'paragraph') { return MyParagraphRichTextNode } } function MyComponent({ richTextNode }) { return ( <> <h1>Article</h1> <UniformRichTextNode node={richTextNode} resolveRichTextRenderer={resolveRichTextRenderer} /> </> ) }

Following is the list of internal node types and their default render elements:

Nodenode.typeDefault rendererNotes
Headingheading'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
Paragraphparagraph'p'
Listlist'ul' | 'ol'
List itemlistitem'li'
Linklink'a'
Assetasset'figure'Requires version >= 19.187.0 of the Uniform SDKs
Tabletable'table > tbody'Requires version >= 19.181.1 of the Uniform SDKs
Table Rowtablerow'tr'Requires version >= 19.181.1 of the Uniform SDKs
Table Celltablecell'td' | 'th'Requires version >= 19.181.1 of the Uniform SDKs
Texttext<RAW VALUE>
Tabtab\t

In addition, some nodes have additional properties on them that can be useful when rendering:

node.typePropertiesNotes
headingtag - 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'

paragraph

format (optional) - 'center' | 'end' | 'justify' | 'left' | 'match-parent' | 'right' | 'start'

direction (optional) - 'ltr' | 'rtl' | null

Use the isPureTextAlign and isPureDirection helpers exported from Uniform @uniformdev/richtext SDK to check if the values from format and direction should be applied to style and dir attributes of a paragraph respectively.

list

tag - 'ul' | 'ol'

start - number

If start is > 1, you should set it to the list start attribute.

list-itemvalue - numberIf value is > 0, you should set it to the list item value attribute.
linklink - { type: 'projectMapNode' | 'url' | 'tel' | 'email'; path: string; nodeId?: string; projectMapId?: string; }Use the linkParamValueToHref helper exported from Uniform @uniformdev/richtext SDK to convert a link parameter value to a href attribute.
asset__asset - Properties of the embedded asset
table
tablerow

tablecell

headerState - number

0: no header, 1: row header, 2: column header, 3: row and column header

Use the getRichTextTagFromTableCellHeaderState helper exported from Uniform @uniformdev/richtext SDK to get a tag name for a table cell depending on its headerState.

text

format - number

text - string

Use the getRichTextTagsFromTextFormat helper exported from Uniform @uniformdev/richtext SDK to get a list of tags for a text node depending on its format.

tab

The Uniform Rich Text parameter is ideal for components leveraging a single piece of content to support an article or campaign. But sometimes you may use structured content from multiple external sources. In these cases, JSON-based rich text that comes from a system with a data structure different from the one provided by Uniform requires slightly different steps to ensure the external rich text renders correctly in your frontend.

To consume rich text data in the frontend, you will need to create a parameter to connect to rich text data in the API response from your chosen external source. First, navigate to the component which you would like to support rich text, and add a new parameter of type JSON Data. Give this parameter any name that you like, for example "Rich text content."

add-json-parameter
The options for adding a JSON parameter to a component.

Once the parameter is configured, you can connect it to any JSON content from external sources. Next, within Canvas, you will create a new data resource which contains rich text content from your integration source. At this stage, you need to select the top-level field which contains the rich text content in JSON format, and connect this data to your component.

contentful-rich-text-json-connection
Example of connecting Contentful rich text to a JSON parameter

tip

Once you have set up a data connection between a JSON parameter and rich text, Uniform recommends saving this configuration as a pattern to make updating the content easier in the future. To find out more, check out the guide on patterns.

To learn more about connecting data to components, check out the connect external data guide.

Once you have connected the JSON rich text data to your component in Canvas, you will need to head to the component on your front end which will resolve the rich text into HTML. Check the documentation for your rich text service, as the steps for processing rich text may vary by front-end framework.

In general, this may involve installing a package from the service that can handle the compilation of HTML from the JSON data that you have already connected to Canvas.

Connecting multiple rich text sources

If you are using a project with multiple integrations, there may be a case where you need to support rich text from multiple sources on the same component. In these cases, Uniform recommends following the same steps as above and to use the frontend to determine the correct package for compiling the resulting JSON data into HTML.