HTML debris in WooCommerce product descriptions

Paste a product description from Word and the paragraph arrives with a crowd: MsoNormal classes, empty <o:p> tags, conditional comments and a font declaration on every line. CatalogLift finds every product description and short description that carries that debris, shows you what it saw, and cleans it for your approval — without touching a single word of the text.

Content & SEO Low severity Fix in CatalogLift

Why Word markup in a description holds products back

A description is meant to be text wrapped in a few tags. What a word processor pastes in is text buried under markup that no browser needs and no editor wrote — and it stays there for years, because it is invisible in the visual editor and only shows up when something looks slightly off.

  • The theme loses control of the typography. Inline font-family and font-size declarations override your stylesheet, so one product renders in Calibri at 11pt while its neighbours use the store's own type. Dark-mode themes and mobile breakpoints break in the same way.
  • Pages get heavier for nothing. A short paragraph can carry several kilobytes of mso- declarations, <o:p> tags and comment blocks. That is weight on every product page and every category listing that prints the short description.
  • Empty paragraphs push the content down. Runs of <p>&nbsp;</p> open gaps between the heading, the price and the actual copy — the reader scrolls past white space to find out what the product is.
  • Feeds and exports carry it along. Product feeds, marketplace listings and CSV exports take the description as it is stored, debris included, and downstream systems are far less forgiving of it than a browser.

How to find HTML debris in descriptions manually

Descriptions live in wp_posts: the long description in post_content and the short one in post_excerpt. This WP-CLI query lists published products where either field carries the commonest Word leftovers:

wp db query "SELECT ID, post_title
FROM wp_posts
WHERE post_type = 'product' AND post_status = 'publish'
  AND (
    post_content LIKE '%class=\"Mso%' OR post_excerpt LIKE '%class=\"Mso%'
    OR post_content LIKE '%<o:p>%' OR post_excerpt LIKE '%<o:p>%'
    OR post_content LIKE '%mso-%' OR post_excerpt LIKE '%mso-%'
    OR post_content LIKE '%<!--[if%' OR post_excerpt LIKE '%<!--[if%'
    OR post_content LIKE '%<p>&nbsp;</p>%' OR post_excerpt LIKE '%<p>&nbsp;</p>%'
  )
LIMIT 50;"

Adjust the table prefix if yours isn't wp_. Add post_status = 'draft' or 'private' to the filter if you want unpublished products too.

The list is the easy part. The query only knows the patterns you typed — an empty paragraph written as <p><br></p> or an <o:p> tag with attributes slips past it — and it cannot tell you what to remove without breaking the page. Then someone opens each product, switches the editor to code view, and cuts by hand, hoping the table width or the store's own class names survive the pass. Next quarter's supplier import brings the same paste back.

How CatalogLift finds and cleans it

Every scan reads the description and the short description of every synced product and looks for a mark that only a word processor leaves: an Mso class name, an Office-only tag such as <o:p>, a conditional comment, a style declaration naming an mso- property or Word's tab-stops — or a paragraph that holds nothing but whitespace, a non-breaking space or a line break. Fields that are empty are skipped, and shortcodes are left alone. Each match becomes a low-severity finding for that one field, with the pattern it saw and a preview of the current value as evidence, so the description and the short description of one product are two findings rather than one blur.

The fix is computed, not written. There is no AI in this check: CatalogLift derives the cleaned value from the same rule that raised the finding — Word tags, comments and Mso class tokens removed, empty paragraphs dropped, and inline typography stripped only where a Word marker proves it was a paste rather than your choice. Layout properties and unrecognized styles stay. You see the before and after as a diff, approve it, and nothing reaches WooCommerce before that decision; nothing in your store changes before that. The next scan confirms the debris is gone, and because CatalogLift keeps watching, the next paste from Word becomes a fresh finding instead of a silent regression.

Fair questions, straight answers.

What counts as HTML debris in a product description?

Markup that a word processor left behind rather than anything you or your editor wrote: Mso class names, <o:p> and other Office-only tags, conditional comments, mso- style declarations, and paragraphs that hold nothing but whitespace or a non-breaking space. Shortcodes are not counted, because there is no way to tell an orphaned one from a working one without your plugin list.

Will the cleanup change how my description looks?

It only subtracts. Word-only tags, comments and class names are removed, and inline typography such as font-family, font-size, color or line-height is stripped only from a description that also carries a mark of Word. Widths, floats, borders and any property the rule does not recognize stay in place, so a specification table keeps its layout, and your own class names survive next to the Mso ones that go.

Does the AI rewrite the description?

No. This is a deterministic cleanup with no AI involved. CatalogLift computes the cleaned version of the description in front of you as a before/after diff, you approve it, and nothing reaches WooCommerce before that decision. The next scan verifies the debris is gone.

What if I styled a heading red on purpose?

Then nothing is flagged for it. Colour and font declarations on their own are treated as your decision; they only come out of a description that carries a Word marker somewhere else in it — an Mso class, an Office tag, a conditional comment or an mso- property.

See it on your own catalog.

Create a free account, connect your WooCommerce store and this check runs on your real products, along with the rest.

No card required. The free plan never writes to WooCommerce.