Shopify rich text vs markdown — how Specter round-trips article bodies
If you’ve spent any time in Shopify’s article editor, you know it’s a rich-text box. You bold something, you make a heading, you drop in an image. Under the hood, Shopify stores all of that as HTML — not markdown, not a block tree, just a chunk of HTML in the article’s body_html field. That’s what the Admin API returns and what it expects back.
Specter does its work in markdown. Every article on your disk is a .md file. So every sync involves a conversion: HTML on the way down becomes markdown, and markdown on the way up becomes HTML. This guide is the honest version of what survives that round trip cleanly and what doesn’t, so there’s no mystery the first time you sync.
Why round-trip through markdown at all
A reasonable question: if Shopify stores HTML, why not just keep your local copy as HTML and skip the conversion?
Two reasons.
The writer is faster in markdown. Headings are #, lists are -, links are [text](url). There’s nothing to format and nothing to misclick. You write the article, you don’t decorate it.
The AI is faster in markdown too. Every AI tool worth using — Claude, ChatGPT, Gemini, Cursor, Copilot — handles markdown natively. They understand the structure without having to parse a tag soup, they produce clean markdown without having to remember to escape attributes, and the diff between two versions is readable. Hand Claude an HTML blob and it’ll work, but it’ll also drift. Hand it a .md file and it edits the way you’d edit it.
Markdown is the lingua franca between your fingers, your AI, and your version-controlled folder. The HTML lives in Shopify, where it belongs.
What round-trips cleanly
These survive the HTML-to-markdown-to-HTML loop with no loss of meaning and no surprises in the Shopify article view:
- Paragraphs. Plain text, normal breaks, nothing surprising.
- Headings.
<h1>through<h6>map to#through######and back. Heading IDs are preserved where Shopify generates them. - Bold, italic, strikethrough. Standard markdown to standard HTML and back.
- Ordered and unordered lists. Nesting is preserved.
- Links. Both inline (
[text](url)) and the underlying<a href>round-trip with theirtargetandrelattributes intact. - Blockquotes. Single-level and nested.
- Code blocks and inline code. Fenced code blocks round-trip with their language hint where you set one.
- Horizontal rules.
---to<hr>and back. - Images by URL. Standard markdown image syntax (
) round-trips with the alt text and source URL preserved. Specter does not re-upload images on every sync — the URL stays the URL. - Tables. Round-trip through GitHub-flavored markdown table syntax.
If your articles are mostly prose, lists, headings, links, and the occasional image — i.e., what a normal blog article actually is — you’ll never notice the conversion is happening.
What’s lossy (and what we do about it)
Some things in Shopify’s rich-text editor don’t have a clean markdown equivalent. Rather than silently dropping them or guessing, Specter preserves them as opaque HTML blocks in the markdown file. They’re clearly marked, they round-trip back to Shopify exactly as they came, and you can leave them alone or rewrite them as plain markdown if you want.
The main offenders:
- Embedded Shopify product cards in articles. If you’ve used the article editor’s “insert product” widget, the result is a Shopify-specific block that has no markdown analogue. Specter preserves it verbatim so it renders correctly when synced back.
- Embedded video/iframe blocks. YouTube embeds, Vimeo embeds, generic
<iframe>tags. Kept as raw HTML in the markdown file. - Custom HTML the article editor lets you paste in. Anything pasted into the editor’s “Show HTML” view is treated as opaque and round-tripped exactly.
- Inline styles and class attributes. Shopify’s editor sometimes attaches
style=""or class names to elements. Specter preserves these on the round-trip rather than stripping them, so your theme CSS keeps working.
“Opaque” here means readable and editable. You can see the HTML in the .md file, you can hand it to Claude and ask it to rewrite the surrounding paragraphs without touching the block, and you can delete the block entirely if you want. What Specter won’t do is silently convert a Shopify-specific block into a <p> and hope you don’t notice.
What this means for AI editing
The practical version of all of the above:
For prose work, markdown is the right tool. When you edit articles with Claude, ChatGPT, or Gemini, the AI is reading and writing exactly what you’d write by hand. The conversion happens at the sync layer, not in the editor.
For SEO work, the frontmatter is the field. Title, handle, SEO title, SEO description, tags, summary — all of them are top-of-file frontmatter, not inside the article body. They’re just lines in the file. That’s why a bulk SEO pass is so easy: the AI doesn’t have to parse the body to update a meta description.
For articles with embedded product cards, give the AI clear instructions. A useful prompt looks like: “Rewrite the prose around the embedded HTML blocks but leave the blocks themselves untouched.” Every AI worth its tokens will follow that.
When the round-trip might surprise you
A few honest edge cases:
- You edited the same article in the Shopify admin and locally. Specter’s conflict prompt catches this — you choose which version wins. The conversion isn’t to blame; the divergence is.
- You hand-edited an opaque HTML block into broken markup. The next push will send broken HTML to Shopify, and Shopify’s editor will render it as best it can. Treat the opaque blocks like the HTML they are.
- You pasted Word-formatted content into the Shopify editor before Specter ever touched the article. Word HTML is famously dirty. The first sync down will normalize the worst of it, but a few stray
<span>tags may survive.
None of this is a deal-breaker; it’s the price of HTML being the storage format on the Shopify side. The point of the markdown layer is that, for the 95% of your article body that’s prose, it’s invisible.
The mental model
Shopify stores HTML because Shopify is a CMS. You and your AI work in markdown because markdown is the format both of you actually want to write. Specter converts between the two on every sync, preserves the things that don’t have a clean markdown equivalent as opaque blocks, and gets out of the way. Your article looks the same in the Shopify admin after the round trip as it did before — that’s the test, and that’s the bar.