When spacing needs attention
Whitespace is invisible in the editor and in most storefront themes, which is exactly why it survives. It is still there in the bytes that every other system reads.
- SKUs may stop matching. A trailing tab or a doubled space inside a SKU changes its exact value. Whether that affects your ERP, product feed or barcode lookup depends on how that system compares SKUs.
- Exact comparisons may differ. Two titles that differ only by a non-breaking space can compare differently in systems that preserve those characters. Systems that normalize whitespace may treat them as equal.
- Hidden characters need review. Zero-width characters may be accidental, but some scripts use them intentionally. A spacing finding alone does not show that a feed rejected the product. Review the marked characters before cleaning.
- Copy reads as careless. A description with a space before every comma or wide gaps between words is a small signal that the rest of the page might be just as unchecked.
How to find whitespace noise manually
With WP-CLI you can catch the most common cases in titles and SKUs with pattern matching. Doubled spaces and a space before a comma or a full stop are easy; the invisible characters take a byte-level check:
wp db query "SELECT p.ID, p.post_title, m.meta_value AS sku
FROM wp_posts p
LEFT JOIN wp_postmeta m ON m.post_id = p.ID AND m.meta_key = '_sku'
WHERE p.post_type IN ('product', 'product_variation')
AND (
p.post_title REGEXP '[[:space:]]{2,}'
OR p.post_title REGEXP '[[:space:]][,.]'
OR p.post_title LIKE CONCAT('%', UNHEX('C2A0'), '%')
OR p.post_title LIKE CONCAT('%', UNHEX('E2808B'), '%')
OR m.meta_value REGEXP '[[:space:]]'
);"
Adjust the table prefix if yours isn't wp_. Extend the
UNHEX checks to post_content and
post_excerpt for descriptions.
The query answers, with gaps. Each invisible character needs its own byte sequence, so it finds only the ones you thought to list. Applied to descriptions it will also match spacing inside HTML attributes and inside preformatted blocks, where the spaces belong. It tells you a row is affected but not which character, and it does not produce the cleaned value or write it back. And it runs once: the next CSV import brings the same noise straight back.
How CatalogLift finds and cleans it
Every scan reads the title, description, short description and SKU of
each current synced product and checks the text outside HTML tags for
doubled spaces or tabs, non-breaking spaces standing in for ordinary
ones, zero-width characters, and a space before a comma or a full
stop. Spacing inside pre, code and
textarea blocks is left alone, and a non-breaking space
before a semicolon, colon, exclamation mark or question mark is
treated as the French typography it usually is. Damage only at the
very edges of a value is not reported by itself, so a trailing newline
WordPress adds to a description does not become a finding.
Each finding is scoped to one field of one product and carries the field name, a preview of the current value and the first kind of noise it found as evidence. In prose fields it is raised at low severity; in a SKU, where exact matching may matter, at high.
There is no AI involved. The same rule that found the noise computes the cleaned value inside CatalogLift, tidying the edges as well once it has a reason to touch the field, and you see it as a before/after diff. Nothing changes in your store except on your authority; once it is decided, CatalogLift writes the cleaned field to WooCommerce and the next scan verifies it is gone. Because CatalogLift keeps watching, an import that reintroduces the noise shows up as a fresh finding instead of a silent regression.