Text encoding artifacts in WooCommerce product text

A product page that reads “Café au lait” or “Men’s jacket” tells the shopper that nobody looked at it. CatalogLift finds every title, description, short description and SKU carrying leftovers of a broken encoding conversion — with the damaged run quoted as evidence and a reviewed repair where one can be trusted.

Content & SEO Medium severity Fix in CatalogLift

Why encoding artifacts cost you trust and sales

Encoding damage is rarely a single typo. It arrives in bulk — one import, one migration, one supplier feed — and lands in exactly the fields the shopper reads first. Because each broken character still looks like a letter, most stores never notice until a customer points it out.

  • The product looks abandoned. “é” in a title and ““” around a quote read as neglect, and a shopper who suspects the listing is stale rarely trusts the stock level or the price either.
  • Search snippets carry the damage. A mojibake title becomes a mojibake headline on the results page, and the same characters break keyword matching for the accented words buyers actually type.
  • Feeds and identifiers stop matching. A SKU with a stray “” no longer matches the warehouse or the marketplace listing, and a description with & renders the entity code literally in every channel that consumes it.

How to find encoding artifacts manually

The most common signatures are the two-character sequences a UTF-8 byte pair turns into when it is read as Windows-1252, plus the doubled HTML entity. With WP-CLI, this query lists published products carrying the frequent ones in the title or either description:

wp db query "SELECT ID, post_title
FROM wp_posts
WHERE post_type = 'product' AND post_status = 'publish'
  AND (
    post_title LIKE '%Ã%' OR post_title LIKE '%â€%'
    OR post_content LIKE '%Ã%' OR post_content LIKE '%â€%'
    OR post_excerpt LIKE '%Ã%' OR post_excerpt LIKE '%â€%'
    OR post_content LIKE '%&%' OR post_excerpt LIKE '%&%'
  )
LIMIT 50;"

The SKU lives in wp_postmeta under _sku, so it needs a second query against meta_value. Adjust the wp_ prefix if yours differs.

The gaps are real. A LIKE '%Ã%' check also matches correctly written French, Portuguese and Italian, so the list needs a human to sort damage from language. It says nothing about how many runs a field carries or where they sit. Repairing the text by hand means recovering the original character for each run, and it can be undone by the very next import — with nothing to tell you the damage is back.

How CatalogLift finds and repairs it

Every scan reads the title, description, short description and SKU of each current product in the synced catalog and looks for two patterns: runs of characters that match the shape of UTF-8 read back as Windows-1252, and HTML entities that have been encoded twice, such as & or ’. A run only counts as damage when decoding it actually produces different valid text — ordinary accented words such as “voilà” or “Qualità” decode to nothing new and are left alone. Each affected field becomes its own finding, with the field name, a preview of the current value, the number of occurrences and the first damaged run as evidence. Findings in the text fields are raised at medium severity; a damaged SKU is raised at high, because other systems match on it.

There is no AI in this check. CatalogLift computes the repair deterministically by reading each damaged run back the way it was written and collapsing the doubled entities, and it only offers that repair when the result is valid text that no longer trips the rule and does not change on a second pass. You see the before/after diff, approve it, and nothing reaches WooCommerce before that decision; the next scan verifies the artifacts are gone. Where the repair cannot be trusted — text damaged twice can have more than one plausible reading — the finding stays open with its evidence and you correct the text in WooCommerce. Either way CatalogLift keeps watching, so an import that brings the damage back becomes a fresh finding rather than a quiet regression.

Fair questions, straight answers.

What is mojibake and where does it come from in WooCommerce?

Mojibake is text that was written in one character encoding and read back in another, so a single character such as é turns into two such as é, and a curly apostrophe into ’. In WooCommerce it usually arrives with a CSV import, a database migration, or a paste from a supplier feed that declared the wrong charset.

Which product fields does CatalogLift check?

The title, the description, the short description and the SKU of every current product in the synced catalog. Each damaged field becomes its own finding, so a product with a broken title and a broken description shows up twice, each with the field named.

Does the AI rewrite the damaged text?

No, this check has no AI step. CatalogLift reads the damaged run back through the encoding it came from and offers the result as a before/after diff for you to approve; nothing reaches WooCommerce before that decision, and the next scan verifies it. When the repair cannot be trusted to reconstruct the original, the finding stays and you fix the text in WooCommerce instead.

Why is a broken SKU treated as more serious than broken prose?

A SKU is an identifier that feeds, warehouses and marketplaces match on, so a stray character in it breaks the match outright. The same characters in a description are only untidy, which is why the SKU case is raised at high severity and the text fields at medium.

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.