Limited Functionality of Rich Text Field in Metaobjects

Topic summary

Limited functionality of metaobject rich text fields compared to product fields, with restricted formatting, no media embeds, and no full HTML editing. Content is stored as a JSON abstract syntax tree (AST), which limits available elements, likely to support cleaner, more structured data (e.g., headless builds).

Supported elements observed: headings (H1–H6), paragraphs, bold/italic text, links (url/title/target), and ordered/unordered lists. Constraints: the root node must be first; only headings, paragraphs, and lists are allowed under root; elements like divs and images cannot be direct children. Tables are not supported, causing issues for size guides; some resort to pasting HTML into plain text.

Workarounds: update metaobject rich text via the Admin API or a custom app; convert HTML to the AST by inspecting network payloads to infer the schema. Rendering tip in Liquid: reference the metaobject via metafield.value and apply metafield_tag to the correct property (omit “.content” unless that is the field name). Outcome: this approach successfully displayed rich text after adjusting the property name.

Documentation is currently lacking; requests for official guidance and broader support remain open. No formal resolution; feedback has been forwarded.

Summarized with AI on January 8. AI used: gpt-5.

Hello forum members

I’ve noticed that the rich text field within metaobjects has limited functionality compared to fields for products and other entities. Can anyone explain why this is the case? Specifically, the limitations I’ve observed include restricted formatting options, the inability to embed media, and a lack of advanced editing features (for instance html). I’m interested in understanding the reasoning behind these limitations and if there are any workarounds available.

Thanks!

Uncle Figumari

metaobject #richtext metafield #htmleditor

1 Like

Hey @Figumari

Those fields can be modified via the Admin API, so a workaround could be to make/use an app. However, the content of the rich text fields appears to be JSON / AST and could have limited elements. I suspect this is to make the data more useful (for example, in a headless build).

Here’s some example text:

And the generated value:

{
  "type": "root",
  "children": [
    {
      "type": "paragraph",
      "children": [
        {
          "type": "text",
          "value": "Hello "
        },
        {
          "type": "text",
          "value": "test bold",
          "bold": true
        },
        {
          "type": "text",
          "value": ". "
        }
      ]
    }
  ]
}

Our docs fall short on this one. Will pass along your feedback!

Scott,

Any chance that there is documentation for this yet?

I’m trying to convert HTML to the AST, but without knowledge of all the fields, it is a bit difficult.

This limitation is preventing our size guides from being easier to add to products, can we get an update on this? Right now we’ve resigned to using the plain text field to paste html of tables made in other rich editors and it’s highly inconvenient.

I ended up just creating a metaobject with everything I could — headings, bold text, italics, etc:

==================================# Heading 1## Heading 2### Heading 3#### Heading 4##### Heading 5###### Heading 6

This is a paragraph. This is bold text. This is italic text. This is bold and italic text. This is a link.

  • first in unordered list
  • second in unordered list

A paragraph in between

  1. first in ordered list
  2. second in ordered list

==================================

then inspect the network request payload:

{"type":"root","children":[{"type":"heading","children":[{"type":"text","value":"Heading 1"}],"level":1},{"type":"heading","level":2,"children":[{"type":"text","value":"Heading 2"}]},{"type":"heading","children":[{"type":"text","value":"Heading 3"}],"level":3},{"type":"heading","level":4,"children":[{"type":"text","value":"Heading 4"}]},{"type":"heading","level":5,"children":[{"type":"text","value":"Heading 5"}]},{"type":"heading","level":6,"children":[{"type":"text","value":"Heading 6"}]},{"type":"paragraph","children":[{"type":"text","value":"This is a paragraph. This is "},{"type":"text","value":"bold text","bold":true},{"type":"text","value":". This is "},{"type":"text","value":"italic text","italic":true},{"type":"text","value":". This is "},{"type":"text","value":"bold and italic text","bold":true,"italic":true},{"type":"text","value":". This is a "},{"url":"https://example.com","title":"Go to an example site","target":"_blank","type":"link","children":[{"type":"text","value":"link."}]},{"type":"text","value":""}]},{"listType":"unordered","type":"list","children":[{"type":"list-item","children":[{"type":"text","value":"first in unordered list"}]},{"type":"list-item","children":[{"type":"text","value":"second in unordered list"}]}]},{"type":"paragraph","children":[{"type":"text","value":"A paragraph in between"}]},{"listType":"ordered","type":"list","children":[{"type":"list-item","children":[{"type":"text","value":"first in ordered list"}]},{"type":"list-item","children":[{"type":"text","value":"second in ordered list"}]}]},{"type":"heading","level":3,"children":[{"type":"text","value":""}]}]}

From that you can generate a JSON schema or Typescript types:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Generated schema for Root",
  "type": "object",
  "properties": {
    "type": {
      "type": "string"
    },
    "children": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "children": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                },
                "bold": {
                  "type": "boolean"
                },
                "italic": {
                  "type": "boolean"
                },
                "url": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "target": {
                  "type": "string"
                },
                "children": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string"
                      },
                      "value": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "value"
                    ]
                  }
                }
              },
              "required": [
                "type"
              ]
            }
          },
          "level": {
            "type": "number"
          },
          "listType": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "children"
        ]
      }
    }
  },
  "required": [
    "type",
    "children"
  ]
}

It’s a pretty basic ast, but if you’re trying to convert HTML to it, there are some gotchas (especially if the HTML is not valid, like mine was):

  • root has to be the first node
  • only headings, paragraphs, and lists can be under the root
    • no divs, imgs, anchors, etc, can be a child of the root

You can already do all that with the existing rich text type, also I need tables, and I can’t imagine a worse way to construct a table than that lol.

2 Likes

Hello,

Can anyone provide me with a solution for this code? I created a metaobject with a richtext field and referenced it with a metafield. When I tried to display data for that metafield, I got this response. I tried filters like metafield_text or metafield_tag, but these filters are not working with the reference object. Is there anybody who can let me know how I can extract the value from it?

{“type”:“root”,“children”:[{“type”:“paragraph”,“children”:[{“type”:“text”,“value”:“Density indicates how much the foam weighs. For example, a cubic foot of four lbs/ft density foam weighs four pounds. The density of memory foam often determines many mattress characteristics as well as many differences between brands / models. You can often learn much about a memory foam mattress simply by knowing its density. In most areas of comparison, low- and medium-density memory foam mattresses tend to perform as well as and often better than high-density memory foam mattresses.”}]}]}

You need something like this:

{%- assign metaobject = product.metafields.namespace.key.value -%}
{{ metaobject.content | metafield_tag }}
2 Likes

Thank you for your response Charles_loder!
I applied the above solution that you provided but it is not working for me. It displays the empty element.

Sorry, you don’t need the content property, that was specific to mine. Replace it with whatever the name of the property is

1 Like

Thank you Charles_loder!
Working for me