Why decorated titles hold products back
A product title travels further than the product page. It becomes the search snippet, the line in a shopping feed, the label on an invoice and the name your team types into wp-admin search. Decoration that looked lively on a marketplace listing costs something in each of those places.
- Search snippets look untrustworthy. A headline wrapped in stars and arrows reads like spam next to plain competitors, and search engines are quick to rewrite titles that look manufactured.
- Feeds and marketplaces reject or downgrade them. Google Merchant Center and most marketplace feeds treat symbols and emoji in a title as a policy problem, so a decorated title can get an item disapproved or buried.
- Nobody can find the product by name. A title such as “★★ Bluetooth Speaker ★★ ➜ Waterproof” doesn't match the words a shopper or a colleague actually types, and the same product exported to another channel keeps its stars along the way.
- It compounds with every import. Decoration arrives in bulk — one supplier feed or one migration can drop it into hundreds of titles at once.
How to find decorated titles manually
Titles live in wp_posts.post_title. With WP-CLI you can
list products whose title contains characters from the common
decorative ranges — dingbats, arrows and the emoji plane:
wp db query "SELECT ID, post_title, post_status
FROM wp_posts
WHERE post_type = 'product'
AND post_status IN ('publish', 'draft', 'private', 'pending')
AND (
post_title REGEXP '[\\\\x{2190}-\\\\x{21FF}]'
OR post_title REGEXP '[\\\\x{2500}-\\\\x{257F}]'
OR post_title REGEXP '[\\\\x{2600}-\\\\x{27BF}]'
OR post_title REGEXP '[\\\\x{1F000}-\\\\x{1FAFF}]'
)
ORDER BY ID DESC
LIMIT 50;"
The backslashes are doubled twice on purpose: the shell keeps one
pair and the SQL string literal keeps one \x{…} escape
for the regex engine. Needs a utf8mb4 column so four-byte
emoji are stored at all. Adjust the wp_ prefix if yours
differs.
The query gets you a list, with three gaps. Hand-picked ranges miss symbols that sit outside them and, worse, catch symbols that belong in a name — a degree sign, a diameter mark, a registered trademark — so every row still needs a human read. It shows the title but not which characters triggered the match. And it answers once; the next supplier import decorates a fresh batch and nobody runs the query again.
How CatalogLift finds and cleans it
Every scan reads the title of each current product in the synced catalog — published, draft, private or pending — and looks for symbols by Unicode category rather than by a word list: symbol-other characters, dingbats, arrows, box-drawing characters and the emoji planes, together with the skin-tone and variation modifiers attached to them. Symbols that carry meaning in a name — ®, ™, ©, °, µ, fractions, currency signs, ⌀, ✓ and the musical accidentals — sit on a fixed protected list and never count. Each symbol is judged on its own, so an arrow between two dimensions is caught while the degree signs around it stay.
Each finding names the field, shows how many decorative characters were found and a sample of them, and quotes the current title as evidence, at low severity next to everything else the scan surfaced. Because the check is deterministic, the fix is too: CatalogLift computes the cleaned title with the same rule — decorative symbols replaced by a space, doubled spaces collapsed, protected symbols kept in place — and shows you the before/after diff. Nothing changes in WooCommerce except on your authority; once decided, CatalogLift writes the clean title and the next scan verifies it landed. If a later import decorates the title again, it comes back as a fresh finding rather than a silent regression.