Reverse text

Backwards text, done three ways so you can see which two are wrong. Reversing 🇬🇧 by code point gives 🇧🇬, which is a different country. Nothing you type here leaves your browser. It is worked out on your own device, so there is nothing to send and nothing to log — which matters more for text than for most things, because people paste in work they are not supposed to paste anywhere.

Reverse the Union Flag and you get Bulgaria

🇬🇧 is not a picture. It is two letters — G and B, written as regional indicator symbols — which a font draws as one flag.

Reverse it the usual way and you get B then G, which is drawn as 🇧🇬. That is the flag of Bulgaria. Not a broken glyph, not a question mark: a different country, rendered perfectly, with nothing to tell you anything went wrong.

Three answers, two of them wrong

MethodWhat it breaks
split("").reverse() cuts anything outside the basic range in half — emoji become question marks
[...str].reverse() keeps those whole and takes apart everything built from several code points
by grapheme nothing — it matches what a reader sees

The usual fix for the first bug fails more cases than the bug did. Across eight test strings, split("") broke four and the spread operator broke five — and not the same five. Spreading handles surrogate pairs, which is the thing everybody knows about, and does nothing at all for combining accents, skin tones, flags or families.

The accent ends up on nothing

"café" can be stored two ways: with a single é, or with a plain e followed by a combining acute accent. They look identical and they behave completely differently.

Reverse the second one by code point and the accent comes off the e and lands at the front of the string, where there is no letter for it to sit on. The browser draws it on nothing. Reversed by grapheme the accent stays attached, because the e and its accent are one character.

How this page knows

Correct reversal needs Intl.Segmenter, which tells you where one character ends and the next begins according to the Unicode rules rather than by counting bytes. It is built into current browsers.

Where it is missing this page says it is missing rather than quietly falling back to the code point answer and calling it characters, which is the bug the whole page is about.

Where to go next