THAI, KHMER, MYANMAR
UNICODE U+200B
Zero Width Space (U+200B): Copy, Type, Find and Remove It
Copy it, type it, spot it and delete it. A practical guide to U+200B and its zero width siblings for developers, writers and anyone who just wants a blank message.
$ node app.js
SyntaxError: Expected property name or '}' in JSON at position 1
$ # the file looks fine, so x-ray it
$ cat config.json
MacBook Pro
PASTED FROM TERMINAL
SCANNING
Zero width characters removed. JSON.parse reads the file again.
PASTED FROM TERMINAL
SCANNING
Zero width characters removed. JSON.parse reads the file again.
Short answer
​ in HTML or "\u200B" in code, and remove it with the regex [\u200B-\u200D\u2060\uFEFF].THE BASICS
What is a zero width space?
One code point, three bytes, zero pixels.
U+200B ZERO WIDTH SPACE sits in the General Punctuation block of Unicode. The official code chart lists it as "commonly abbreviated ZWSP" and describes its job in one line, quoted below. Fonts draw nothing for it, so you cannot see it, select it on its own or tell it apart from no character at all.
Its real purpose is line breaking. Put a ZWSP inside a long word or URL and the browser may wrap the line there without adding a hyphen. Languages written without spaces between words, such as Thai, Khmer and Myanmar, use it to mark word boundaries for line breaking.
The trouble starts when it lands where nobody wanted it. A ZWSP copied out of a web page, a CMS or a rich text editor travels into code, spreadsheets and logins, and the software on the other end treats it as a real character. That is why searches for this character come from two camps: people who want one, and people trying to get rid of one.
This page covers the zero width family in depth. If you need to check text for every kind of invisible code point, use the invisible character detector. For how hidden characters differ from AI watermarks, see watermark vs hidden characters.
This character is intended for invisible word separation and for line break control; it has no width, but its presence between two characters does not prevent increased letter spacing in justification.
COPY AND PASTE
Zero width space copy and paste
Need the character itself? Copy it here. Each button copies one character and nothing else.
COPY PAD
Copy a zero width character in one click
Each button puts exactly one invisible character on your clipboard. Paste it into the test field to prove it is there.
Allows a line break with no visible gap.
- UTF-8
- E2808B
- HTML
- ​ ​
- JS
- "\u200B"
- Python
- "\u200b"
Stops two letters from joining.
- UTF-8
- E2808C
- HTML
- ‌ ‌
- JS
- "\u200C"
- Python
- "\u200c"
Glues emoji and letters together.
- UTF-8
- E2808D
- HTML
- ‍ ‍
- JS
- "\u200D"
- Python
- "\u200d"
Blocks a line break with no visible gap.
- UTF-8
- E281A0
- HTML
- ⁠ ⁠
- JS
- "\u2060"
- Python
- "\u2060"
No zero width characters in the field yet.
Will it survive the paste?
THE FAMILY
Zero width characters compared: ZWSP, ZWNJ, ZWJ, word joiner and BOM
Five invisible characters people confuse with each other. They look identical (they look like nothing) but do opposite jobs.
| Character | Code point | UTF-8 bytes | HTML | What it does |
|---|---|---|---|---|
| Zero width space (ZWSP) | U+200B | E2 80 8B | ​ or ​ | Allows a line break, no visible gap |
| Zero width non-joiner (ZWNJ) | U+200C | E2 80 8C | ‌ or ‌ | Stops neighbors from joining (Persian, Hindi, ligatures) |
| Zero width joiner (ZWJ) | U+200D | E2 80 8D | ‍ or ‍ | Joins neighbors (emoji sequences, Indic conjuncts) |
| Word joiner (WJ) | U+2060 | E2 81 A0 | ⁠ or ⁠ | Forbids a line break, no visible gap |
| Byte order mark (BOM) | U+FEFF | EF BB BF |  | Marks byte order at the start of a file |
Swipe to compare →
Bytes checked with a UTF-8 encoder. U+FEFF used to double as a zero width no-break space; Unicode now points to the word joiner U+2060 for that job.
Do not strip all five blindly
FOUND ONE IN YOUR TEXT?
Paste it once, see every zero width character
ClaudeClean flags zero width spaces, joiners, word joiners, BOMs, no-break spaces and soft hyphens, then removes them in your browser. Nothing is uploaded for the scan.
- 300 rewrite credits a month
- 20,000 characters per request
- .txt, .docx and .pdf files
HOW TO TYPE IT
How to type a zero width space on Windows, Mac, Linux and in code
Every method below was checked against documentation or run locally. The famous Alt code mostly does not work.
| Where | How | Notes |
|---|---|---|
| Microsoft Word, OutlookOur pick | Type 200B, press Alt+X | Converts the hex code before the cursor. Press Alt+X again to turn it back into a code. |
| Windows, other apps | Copy it from this page | Alt+8203 on the numpad gives a control character in Notepad and browsers, not a ZWSP. |
| Windows, hex numpad | Alt, numpad +, then 200B | Only after setting EnableHexNumpad to 1 in the registry and signing in again. |
| macOS | Unicode Hex Input, then Option+200B | Add Unicode Hex Input under Keyboard > Input Sources first. Or run printf '\u200b' | pbcopy. |
| Linux (GTK, IBus) | Ctrl+Shift+U, 200b, Space | Works in most GTK and IBus apps; some terminals and Qt apps differ. |
| HTML | ​ or <wbr> | <wbr> gives the same break opportunity without a character in the text. |
| JavaScript, JSON | "\u200B" | String.fromCodePoint(0x200B) works too. |
| Python | "\u200b" | Or chr(0x200B). print(repr(s)) shows it as \u200b. |
| CSS content | content: "\200B" | CSS escapes take the hex code with no u. |
| URL | %E2%80%8B | The UTF-8 bytes, percent-encoded. |
Swipe to compare →
Want one on the clipboard right now? The copy pad above is the fastest route on any system.
// Browser console (Chrome, Edge, Firefox)
copy("\u200B") // ZWSP on the clipboard
// JavaScript
const zwsp = "\u200B";
zwsp.length // 1
zwsp.trim().length // still 1# macOS Terminal
printf '\u200b' | pbcopy
# Python
zwsp = "\u200b"
print(repr("a" + zwsp + "b")) # 'a\u200bb'
print(zwsp.isspace()) # FalseWhy does Alt+8203 fail? Windows only treats Alt codes above 255 as Unicode in rich edit controls such as WordPad. Most other apps take the number modulo 256, so 8203 becomes 11, a vertical tab. If a video tells you to hold Alt and type 8203, test it in your app before trusting it.
WHAT IT IS FOR
Legit uses of zero width characters
Before you delete every one you find, know where they belong.
LONG URLS AND CODE
Wrapping long strings
<wbr>, which MDN says behaves like U+200B but never ends up in copied text.PERSIAN, HINDI
ZWNJ keeps letters apart
EMOJI
ZWJ glues emoji together
SOCIAL POSTS
Stopping auto-links and mentions
FINGERPRINTING
Tagging copies of a document
ZWJ EMOJI ASSEMBLER
How the family emoji is glued together
Step through the five code points. Then remove the joiners and watch one emoji fall apart into three.
0
Code points
0
JS .length
0
UTF-8 bytes
0
Graphemes
The finished emoji is 5 code points, 8 UTF-16 units and 18 UTF-8 bytes, yet a reader sees one picture. That gap is why character limits, cursors and naive string slicing go wrong around emoji.
FOR DEVELOPERS
Zero width space bugs: JSON, string compares, URLs and trim()
The character is invisible in your editor, your logs and your diff, and most whitespace functions skip it. Here is what breaks and how to see it.
LIVE REVEAL
Paste anything and see the zero width characters
Runs only in your browser. Orange pills are spacers you usually want gone; green pills are joiners that real text and emoji depend on.
X-ray view
6
zero width found
118
JS .length
112
length without them
ZWSP × 3WJ × 1ZWJ × 2
JSON.parse fails
JSON.parse('{\u200B"a":1}')
// SyntaxError: Expected property
// name or '}' in JSON at position 1Position 1 points at a character you cannot see. Node 20 error text shown.
String compare is false
"admin" === "admin\u200B" // false "user" == "us\u200Ber" // false
Logins, role checks, dictionary keys and database lookups miss with no visible reason.
URL returns 404
/v1%E2%80%8B/orders // the ZWSP is sent as three // percent-encoded bytes
One developer traced a failing API call to five ZWSPs pasted into the URL.
TESTED, NOT ASSUMED
Your trim() does not see it
A check means the function catches that character. Almost every cell is an X, which is why zero width bugs survive code review.
| Function | U+200B | U+200C | U+200D | U+2060 | U+FEFF |
|---|---|---|---|---|---|
| JS str.trim()removes it from the ends | |||||
| JS /\s/matches it | |||||
| Python str.strip()removes it from the ends | |||||
| Python str.isspace()returns True | |||||
| Python re \smatches it | |||||
| Unicode NFKCnormalizes it away | |||||
| Python repr()shows it as an escape |
Jul 2021
A social post breaks copied code
Chris Coyier documents the @media trick and the copy-paste risk in CSS-Tricks.Aug 2021
SharePoint search fails in Chrome
A SharePoint 2016 admin reports Chrome inserting ZERO WIDTH SPACE into rich text fields, which broke page search; Edge was the workaround (Microsoft Q&A).Dec 2021
VS Code starts highlighting them
Version 1.63 outlines uncommon invisible characters in source code by default (release notes).Jul 2024
Five ZWSPs in one API URL
A developer blog walks through finding them via VS Code, a %E2%80%8B in the request and the Gremlins extension (post).
FIND AND REMOVE
How to find and remove zero width spaces
Pick the tool you are already in. Each method replaces the character with nothing.
FIND AND REPLACE IN VS CODE
Two invisible bugs, one regex
MacBook Pro
- 01Spot the boxesVS Code 1.63 and later outline invisible characters in code by default.
- 02Open find with regexPress Cmd+Option+F (Ctrl+H on Windows), turn on .* and search \u200B.
- 03Check every matchBoth hits are bugs here: a broken URL and a compare that never matches.
- 04Replace all with nothingLeave Replace empty and hit Replace All. Save the file.
- 01
VS Code
Open Replace (Cmd+Option+F on Mac, Ctrl+H on Windows), turn on regex (.*), search\u200Bor[\u200B-\u200D\u2060\uFEFF]and replace all with nothing. Since 1.63, invisible characters in code get a highlight box; the setting iseditor.unicodeHighlight.invisibleCharacters. Markdown files are not highlighted by default. - 02
Microsoft Word
Open Find and Replace, put^u8203in Find (decimal, not hex), leave Replace empty and click Replace All. Turn off "Sounds like" first or the code search fails, per Microsoft Q&A. - 03
Google Docs
Open Edit > Find and replace, tick Match using regular expressions, search\x{200B}(the RE2 hex syntax) and replace with nothing. Try it on a copy of the document first. - 04
JavaScript
// remove spacers, keep emoji joiners s.replace(/[\u200B\u2060\uFEFF]/g, "") // remove the whole family s.replace(/[\u200B-\u200D\u2060\uFEFF]/g, "")
- 05
Python
import re clean = re.sub(r"[\u200b-\u200d\u2060\ufeff]", "", s) # strip() will not do it: "\u200bhi".strip() # '\u200bhi'
- 06
Command line
# show lines that contain one (GNU grep) grep -nP '\x{200B}' file.txt # delete them in place (any system with perl) perl -CSD -pi -e 's/[\x{200B}-\x{200D}\x{2060}\x{FEFF}]//g' file.txt
No regex at hand?
BLANK NAMES AND MESSAGES
Invisible usernames and blank messages
A big share of people searching for this character want a name or message that looks empty. Here is what to expect.
THE BLANK MESSAGE TRICK
A message that looks empty is not empty
- 01The bubble holds one characterU+200B is 3 bytes in UTF-8 (E2 80 8B), so the app sees a non-empty message.
- 02It has no width and no glyphFonts draw nothing for it, so the bubble renders with only its padding.
- 03Apps can strip itMany inputs trim or reject text made only of invisible characters. Same for display names.
What tends to work
- Messages and bios A single ZWSP often gets through chat apps and text fields because the field is not technically empty.
- Spacing tricks Putting a ZWSP between line breaks can keep an app from collapsing empty lines in a bio or caption.
- Testing first Paste into the real field and preview before you save. Behavior changes with app updates.
What tends to fail
- Trimmed input Many sign-up forms strip or reject names made only of invisible characters.
- Other blank characters Some guides suggest Hangul filler (U+3164) or braille blank (U+2800). They are not zero width, and platforms block them too.
- Impersonation A name with hidden characters can look identical to someone else's. Platforms treat that as abuse.
To check which blank-looking characters a piece of text holds, paste it into the invisible character detector. It lists every code point, not just the zero width ones.
THE AI QUESTION
Do ChatGPT and Claude add zero width spaces?
Short version: there is no public evidence that either inserts U+200B on purpose. The one documented case involved a different character.
Apr 20, 2025
Odd spaces in o3 and o4-mini answers
Rumi reported narrow no-break spaces, U+202F, in longer answers from OpenAI's o3 and o4-mini, and none in GPT-4o (Rumi). Not zero width spaces.Apr 22, 2025
OpenAI: not a watermark
Rumi's update quotes OpenAI calling the characters a quirk of large-scale reinforcement learning, not a watermark.Apr 23, 2025
The pattern stops
Rumi: "In our latest testing, we are no longer seeing special characters and this issue seems to have been resolved."Oct 13, 2025
U+202F again, reported by users
A thread on the OpenAI developer forum reports GPT-5 (non-reasoning) using U+202F instead of normal spaces. A user report, not an OpenAI statement.Aug 14, 2026
Anthropic describes Claude's watermark
Anthropic says the mark lives in word choice: "Nothing is added to the text and there are no hidden characters" (Anthropic).Oct 5, 2026
OpenAI starts textGrain in the EU
OpenAI's EU text watermark is statistical too, and its help center says it adds no hidden characters.
Nothing is added to the text and there are no hidden characters.
So where do zero width spaces in AI-written text come from? Usually from the path, not the model: chat interfaces, rich text editors, CMS fields and copy-paste between apps. Reddit threads claiming ChatGPT hides ZWSPs in every answer exist, but none we found came with a reproducible test. Removing hidden characters is still worth it because they break word counts, search and code. It does nothing to a statistical watermark, which lives in word choice. For the full picture on OpenAI text, see the ChatGPT watermark remover guide.
KEEP OR DELETE
When to keep a zero width character and when to delete it
A quick decision guide by context.
Keep it
- Emoji sequences ZWJ inside family, profession and flag emoji. Removing it splits the emoji.
- Persian, Urdu, Hindi and other scripts ZWNJ and ZWJ change spelling and rendering. Ask a native reader before stripping.
- Thai, Khmer, Myanmar ZWSP marks word boundaries for line breaking.
- Deliberate layout A ZWSP placed on purpose to allow a break in a long URL on a web page (though <wbr> is cleaner).
Delete it
- Code and config Identifiers, strings, JSON, YAML, env files. Any ZWSP here is a bug waiting to happen.
- URLs, emails, IDs One hidden byte turns a valid link or login into a 404 or a failed match.
- Data you will search or compare Spreadsheet cells, database fields, tags, slugs and filenames.
- Pasted prose Essays, posts and documents copied between apps. In English text it has no job to do.
SEE IT WORK
Paste text, see the zero width characters, clean them
ClaudeClean is named for Claude, but the scanner treats any pasted text the same way.
> source text
Paste or drop a file
Paste text or upload a .txt, .docx or .pdf. Up to 2,000 characters works without an account.
scan report
3 zero-width1 soft hyphencleanable signals2Scan in your browser
Zero width spaces, joiners, word joiners, BOMs, no-break spaces, soft hyphens and lookalike letters are marked and removed locally. Your text is not stored.
before → after
clearusefulanswerfocusedhelpfulresponse
Copied ✓Rewrite only if you want
An optional rewrite smooths AI habits with a before and after diff. It sends text to OpenAI and is best effort, with no detector result promised.
PRICING
Clean the text free. Rewrite more with Pro.
The scan and hidden-character cleanup are free. Pro adds room for rewrites and files.
CLAUDECLEAN PRO
ClaudeClean Pro
Cancel anytime.
- 300 credits every month (≈300,000 characters of rewriting)
- 20,000 characters per request
- Clean .txt, .docx and .pdf files
- Light / medium / strong intensity
- Dashboard with history
Free: 10 credits a month with an account, or try 2,000 characters right here without one. Strong rewrites cost 2× credits.
GLOSSARY
Zero width terms in plain English
- ZWSP (U+200B)
- Zero width space. An invisible line break opportunity.
- ZWNJ (U+200C)
- Zero width non-joiner. Keeps two characters from joining or forming a ligature.
- ZWJ (U+200D)
- Zero width joiner. Asks the font to join neighbors, used in emoji sequences and Indic scripts.
- WJ (U+2060)
- Word joiner. An invisible character that forbids a line break, the opposite of ZWSP.
- BOM (U+FEFF)
- Byte order mark. Belongs at the very start of a file, if anywhere. Elsewhere it is junk.
- Format character (Cf)
- The Unicode category for invisible characters that affect layout or joining. All five above are in it.
- <wbr>
- HTML element that allows a line break, like a ZWSP, without adding a character to the text.
- Grapheme
- What a reader sees as one character. The family emoji is one grapheme made of five code points.
WATCH
Zero width spaces in three minutes
A short general explainer if you prefer video.
SOURCES
Where these facts come from
Standards and vendor documentation first, then real-world bug reports.
Unicode Consortium
General Punctuation code chart (U+2000 to U+206F)
Names, abbreviations and the official notes for ZWSP, ZWNJ, ZWJ and word joiner.
View sourceUnicode Consortium
Emoji ZWJ sequences
The full list of emoji built with U+200D, including family emoji.
View sourceMDN Web Docs
<wbr>: the line break opportunity element
States that <wbr> behaves like U+200B.
View sourceWikipedia
Zero-width space
UTF-8 bytes, HTML entities and use in Thai, Khmer and Myanmar.
View sourceWikipedia
Zero-width joiner and zero-width non-joiner
Emoji sequences, Devanagari conjuncts and Persian examples.
View sourceWikipedia
Alt code
Why Alt codes above 255 only work in rich edit controls, and the EnableHexNumpad setting.
View sourceVisual Studio Code
November 2021 release (1.63)
Unicode highlighting of invisible and ambiguous characters, on by default.
View sourceOffice Watch
Alt+X shortcut in Word and Outlook
Type a hex code and press Alt+X to insert the character.
View sourceMicrosoft Q&A
Find and replace with Unicode codes in Word
^u takes decimal codes; turn off Sounds like.
View sourceGoogle Docs Help
Find and replace
Regular expression matching in Docs.
View sourceRumi
New ChatGPT models seem to leave watermarks on text
April 2025 U+202F findings and the follow-up updates.
View sourceAnthropic
Claude's text watermark
States that no characters are added and there are no hidden characters.
View sourceCSS-Tricks
Zero-Width Space
Chris Coyier on using ZWSP in social posts and the copy-paste risk.
View sourceMicrosoft Q&A
Why does Chrome randomly inject the ZeroWidthSpace?
SharePoint 2016 rich text fields and broken page search.
View sourceFAQ