Repository navigation
Description
Before submitting a new issue
- I tested using the latest version of the library, as the bug might be already fixed. (1.1.1, the latest release; the code below is unchanged on
main@ 0d015a7) - I tested using a supported version of react native.
- I checked for possible duplicate issues, with possible answers. (Related but different: HTML Entity Support #235 / feat: iOS Html entities handling #258 fixed
&<>, and iOS setValue renders numeric HTML entities emitted by Android getHTML as literal text #636 / fix(iOS): rendering numeric entities #638 fixed numeric references.)
Bug summary
On iOS, EnrichedTextInput (and EnrichedText) render the named character reference as the literal six characters . The next getHTML() / onChangeHtml then escapes the &, so the stored HTML becomes &nbsp;. After that, the literal text shows up on every platform, because it is now real text.
is very common input. The HTML serialization algorithm (WHATWG "escaping a string") writes U+00A0 as . So HTML produced on the web (innerHTML, this library's web editor, Tiptap/ProseMirror getHTML()) contains it whenever the text has a non-breaking space. Browsers insert one for a trailing or double space typed in a contenteditable. This library's Android serializer (EnrichedParser.withinStyle) also writes runs of spaces as . So content written on web or Android and then edited on iOS gets corrupted.
Cause: getEscapedCharactersInfoFrom in ios/extensions/StringExtension.mm only maps &, < and >, plus numeric references. Android (TagSoup) and web (DOMParser) decode named references.
Suggested fix: add at least → U+00A0, " → " and ' → ' to unescapeMap. Ideally, decode the full HTML5 named-reference table.
Workaround we use for now: before passing HTML to the component, rewrite / " / ' to   / " / ', which iOS already decodes.
Library version
1.1.1
Environment info
react-native 0.86.2
expo 57.0.14 (dev client, new architecture)
react 19.2.3
iOS Simulator 18.6 (iPhone 16 Pro); also seen on a physical iPhone running iOS 26Steps to reproduce
- On iOS, render an
EnrichedTextInputwith:<EnrichedTextInput defaultValue={'<html><p>Hello world</p></html>'} onChangeHtml={(e) => console.log(e.nativeEvent.value)} />
- Observed: the input shows
Hello world. Expected:Hello world, with a non-breaking space. - Type one character. Observed in
onChangeHtml:…Hello&nbsp;world…. Expected: U+00A0 (or ), not&nbsp;. - The same HTML on Android and web renders correctly.
Reproducible example repository
No standalone repo yet. The steps above use the stock component only, with no app code involved.
Activity
hejsztynx commentedon Oct 19, 2026
Hi @henrikra ! Thank you for submitting this issue. I agree, this is a bug and we'll get it fixed
fix(ios): HTML entities encoding/decoding improvements (software-mans…