WordPress 25.08.2026 · 2 min read

Why Your Croatian and German Characters Turn Into “u0161” in WordPress

How wp_json_encode() without JSON_UNESCAPED_UNICODE and update_post_meta()’s automatic unslash together turn š and an em dash into literal “u0161” and “u2014”.

The symptom looks like database corruption: save text with an em dash — or a letter like š somewhere in WordPress, and the next time you look, it reads literally “u2014” or “u0161” instead of the character. The database is fine — the cause is narrower, and far more common, than it looks.

The Symptom

It usually shows up first wherever someone types a special character by hand — a contact-form placeholder, a product title, imported content. Everything looks correct in the admin while you’re saving it; refresh the page and the character is gone, replaced by a bare hex code.

Two Mechanisms That Don’t Agree

json_encode() — and WordPress’s own wp_json_encode() wrapper — escapes every non-ASCII character as a \u sequence by default: an em dash becomes \u2014, š becomes \u0161. That’s correct, standard JSON.

The problem happens a step later. add_post_meta(), update_post_meta(), and update_option() all call wp_unslash() on the value internally before saving — the mechanism that reverses WordPress’s automatic escaping of $_POST data. wp_unslash() can’t tell the difference between a backslash WordPress added itself and a backslash that’s part of your JSON: it strips both. \u2014 becomes literally u2014.

The Fix

The fix is one line, not a rewrite: json_encode($data, JSON_UNESCAPED_UNICODE) so the character stays a real character instead of an escape, plus wp_slash() around the whole call before handing it to update_post_meta(), so unslash has something harmless to strip instead of your content.

Where Else It Hides

Anything that JSON-encodes data before saving it into a meta field or option is a candidate — form builders, content importers, custom fields. The bug passes tests unnoticed because test data rarely contains diacritics or an em dash, so it only shows up the first time someone actually writes real Croatian or German text.

A bug the English-speaking web almost never finds — one š or one em dash is enough to make it visible.