Repository navigation
Sanitize with DOMPurify by default and add a React Native entry - #1
Merged
Merged
Conversation
The default entry now sanitizes the parsed tree in place with a private DOMPurify instance, so what DOMPurify checked is exactly what renders. On top of DOMPurify's defaults it only removes what reaches past the fragment: <style> and <title>, form/formaction, position: fixed styles and javascript: attribute values. A new `purify` option merges a DOMPurify config over the built-in one, and DOMPurify still runs after a caller's own `sanitize`. A new `react-html5-parser/core` entry keeps the unsanitized parser at about 3 kB, and `react-html5-parser/native` renders HTML to React Native View, Text and Image components. It parses with htmlparser2, bundled into the entry so Metro versions that ignore package exports can resolve it, opens links only for http, https, mailto and tel, and loads images only from http, https and raster data URIs. The parser was audited against React 18 and 19: SVG attributes are mapped by default, form fields stay uncontrolled, React 19 head hoisting and <html>/<body> binding are avoided, and custom elements keep their attribute names. BREAKING CHANGE: react >= 18 is now required (react-native >= 0.71 for the native entry). `parse` from the default entry sanitizes, which grows it to about 15 kB; import from `react-html5-parser/core` to opt out. Entries in `components` render as React components rather than being called as functions, so an inline arrow function remounts its subtree on every render.
Build ESM and CommonJS with tsdown 0.21, which still runs on Node 22.13. CommonJS entries are built one by one: in a shared build rolldown puts its interop helpers in index.cjs, so core.cjs and native.cjs would require it and load DOMPurify. publint runs after every build. Drop the UMD and legacy .module.mjs outputs, and raise the size limits by the 86 B and 10 B the new output costs. CI runs tests and the size check on pushes and pull requests to main.
Describe parse per entry, add an options table and the order in which the options run, and list the other exports. Replace placeholder examples with real ones, fix the attrsMap example that DOMPurify made a no-op, and move longer recipes to EXAMPLES.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
parsefromreact-html5-parserruns a private DOMPurify instance over the parsed tree in place, so the checked tree is the rendered tree (no second parse, no mutation XSS). On top of DOMPurify's defaults it removes only what reaches past the fragment:<style>,<title>,form/formaction,position: fixedstyles andjavascript:attribute values. A newpurifyoption merges a DOMPurify config over the built-in one; DOMPurify still runs after a caller's ownsanitize.react-html5-parser/core. The unsanitized parser, about 3 kB.react-html5-parser/native. Renders HTML to React NativeView,TextandImage. Parses with htmlparser2, bundled into the entry so Metro before 0.79 resolves it. Links open only forhttp,https,mailtoandtel; images load only fromhttp,httpsand raster data URIs. Options:components,tagStyles,textStyle,onLinkPress,mapElement.<html>/<body>binding, custom elements keep their attribute names,attrsMapapplies everywhere.Breaking changes
react >= 18; the native entry also needsreact-native >= 0.71./coreto opt out.componentsentries render as React components instead of being called as functions, so an inline arrow function remounts its subtree on every render, and a component returningundefinedthrows on React 18.mapElementreceives the component element for a mapped tag.Sizes (min + gzip)
react-html5-parserreact-html5-parser/corereact-html5-parser/nativeTest plan
npm test(typecheck + jest): 208/208 on React 19npm run build:sizewithin limits