Inspect Unicode · browser-local
Invisible Character Detector
Reveal hidden formatting code points that can affect matching, moderation, display order, or copy-and-paste behavior. Detection stays separate from removal so meaningful joiners are not deleted without review.
- Index state
- eligible
- Reviewed
- 2026-08-24
- Input limit
- 5,000 graphemes
Invisible Character Detector
U+200BOffset 7Non-ASCII · Zero-width · Invisible
Good fit
Use this tool when
- A username or code looks normal but validation fails.
- Search, deduplication, or moderation behaves unexpectedly.
- You suspect zero-width or bidi manipulation.
Keep the original
Avoid it when
- You intend to delete every joiner automatically.
- You need a guarantee that all spoofing techniques are covered.
- The text uses scripts where joiners carry linguistic meaning.
Reviewed truth vectors
Examples that expose the edge cases
a[ZWSP]bU+200B at offset 1Zero-width space is hidden between letters.
a[ZWJ]bU+200D at offset 1Zero-width joiner may be meaningful.
abc[RLO]defU+202E · Bidi controlRight-to-left override is high risk.
Transparent implementation
How it works
- 01
Inspect each code point and its UTF-16 offset.
- 02
Match reviewed zero-width, invisible, and bidi-control sets.
- 03
Label the type and build a conservative safer version separately.
Known limitations
What the result cannot promise
Some legitimate shaping characters are visually hidden.
The V1 set is high-signal, not every Unicode format character.
Removal can alter emoji sequences and language shaping.
Questions before copying
Frequently asked questions
Are all zero-width characters bad?
No. Joiners and non-joiners can be meaningful in languages and emoji sequences.
What does the offset mean?
It is the JavaScript UTF-16 code-unit offset, useful for locating the exact position in the source string.
Can GlyphSift remove them safely?
It offers a conservative safer version for high-risk controls, but you should review joiners before removal.
Experience, expertise & trust
How we verify this tool
Automated evidence
- Tool-contract & coverage suite30 deterministic cases
tests/tools-30.test.mjs mirrors the ToolRunner dispatch and asserts every registered engineId returns the contracted output shape, plus a coverage guard so no tool silently drops characters.
Run in: node --test after a production build (vinext build) - Rendered-HTML suite12 deterministic cases
tests/rendered-html.test.mjs renders the deployed server bundle and asserts the Unicode-version manifest and each wave's tool markup are present in the server-rendered HTML.
Run in: node --test against the built dist/server bundle - Unicode inspection suite11 deterministic cases
tests/unicode-inspection.test.mjs verifies grapheme/code-point/byte counting and hidden-control detection using explicit \u escapes for combining and bidirectional characters.
Run in: node --test against the runtime's Unicode data - Compatibility risk suite13 deterministic cases
tests/compatibility.test.mjs checks that bidirectional controls, invisible characters, mixed scripts, and NFKC-changing input raise the documented risk status, and that safe-text stripping preserves ordinary content.
Run in: node --test, deterministic analyzer
Standards this tool follows
- UTS #39: Unicode Security Mechanisms
Confusable and mixed-script detection methodology.
- UAX #9: Unicode Bidirectional Algorithm
Bidirectional control characters flagged during inspection.
- UAX #15: Unicode Normalization Forms
NFC/NFKC normalization comparisons.
- RFC 3629: UTF-8
Byte-length counting for the UTF-8 encoding.