HTML string mutation to RichText JSON object for metafields

I am attempting to make updates to metafields using the Admin API with GraphQL. Running into issues regarding the acceptable schema for the JSON object for richtext fields.

So I know I am not the only person to have this issue.

But the documentation seem limited, and have not found any possible NodeJS solutions aside from custom.

The problem I am running into is the JSON object schema keeps throwing errors for things like attributes, and other issues.

I have scoured the web for a solution, and have only found a handful of others that either attempted the same thing or have no solution.

Please help, I need a magic bullet so I can restore my trust in Shopify as a platform. And yes, I have used ChatGPT and CoPilot to assist, and both suffer from major hallucinations regarding the subject, I suspect because the lack of documentation.

I don’t recognize the richtext object format, because I don’t have much experience, but is it possible Shopify is just using some universal format that I don’t know the name of to search for.

Also here is a gist of a kinda working solution in Node

Yeah, you need to ensure that the input you use matches what is acceptable based on the documentation you linked to.

I’m out and about at the moment but took a glance at the JS gist and the approach seemed fine to me.

I would take a look at the element type to see if it is a hyperlink and then just pull the href rather than assume any other attributes would be usable because I believe the documentation says they are not.

Let me know if that helps at all…

I found an example of each element from Shopify, but did not see information related to attributes.

Also curious if this JSON object format is proprietary to Shopify, or if this is from a library. I know many different headless CMS handle richtext this way.

Think the frustrations are the lack of documentation, or any sort of mutation function except for what I found and made.

I am assuming it is proprietary to Shopify.

Specifically, it is just rich text content and there are no attributes used aside from the href and title attributes of a hyperlink. I mean if they offered some sort of “code view” like you get with the page content or product description, maybe anything goes, but for just the rich text type metafield or theme input setting I believe you are limited to what they currently provide/allow.

At least, once you have it working completely, feel free to share here so that others may benefit from the overcoming of the frustrations you have been facing.

I will work on a fix for you and share it here later tonight.

Just wanted to update here. I was unable to get back on tonight so I should have a solution for you tomorrow. Feel free to move onto something else for the time being.

I think for my case my solution has solved about 80% of the data, the other 20% I am just going to hand edit the JSON object.

At one point I found official documentation that showed an example of the JSON object and all the elements… but for the life of me I can’t find it again.

Thanks for all your efforts @RobDukarski - would be good to get the gist in a good working version that can be used by others that might run into this problem.

Are you looking for something like this? I wrote this one for parsing rich text json to HTML so I could add it to the Invoices page because it wouldn’t render properly

{% assign parsed_content = order.metafields.namespace.key | json_parse %}

{% for item in parsed_content.children %}
  {% case item.type %}
    {% when 'paragraph' %}
      <p>
        {% for child in item.children %}
          {% if child.bold and child.italic %}
            <strong><em>{{ child.value }}</em></strong>
          {% elsif child.bold %}
            <strong>{{ child.value }}</strong>
          {% elsif child.italic %}
            <em>{{ child.value }}</em>
          {% else %}
            {{ child.value }}
          {% endif %}
        {% endfor %}
      </p>
      
    {% when 'heading' %}
      {% assign heading_size = 'h' | append: item.level %}
      <{{ heading_size }}>
        {% for child in item.children %}
          <span {% if child.italic %}style="font-style: italic;"{% endif %}>
            {{ child.value }}
          </span>
        {% endfor %}
      </{{ heading_size }}>

    {% when 'link' %}
      <a href="{{ item.url }}" title="{{ item.title }}">
        {% for child in item.children %}
          {{ child.value }}
        {% endfor %}
      </a>

    {% when 'list' %}
      {% if item.listType == 'ordered' %}
        <ol>
      {% else %}
        <ul>
      {% endif %}
      
        {% for list_item in item.children %}
          <li>
            {% for child in list_item.children %}
              {{ child.value }}
            {% endfor %}
          </li>
        {% endfor %}
      
      {% if item.listType == 'ordered' %}
        </ol>
      {% else %}
        </ul>
      {% endif %}
  {% endcase %}
{% endfor %}

Thanks for the code snippet, but this is a solution to the opposite side of my issue. I am attempting to convert HTML into RichText JSON object for submission to the API.

The solution I had worked with a few bugs, but this task is now closed for me. Going to close this topic with my solution in hopes that I can at least start a search trail for someone else who runs across this issue.

Going to make this thread as closed - but here is a working solution (but not perfect) for using Node to mutate HTML string into a RichText JSON object for the Admin GraphQL API

https://gist.github.com/edmeehan/b47642f8972e5df3a0e8460aa3a80a87