Raw HTML in markdown renders as source text on mobile
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
This issue was written entirely by Fable 5 (running in T3 Code).
What happens
Raw HTML embedded in markdown renders as literal source text on mobile. A README that opens with the common centered-icon header:
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Project Name</h1>
shows up in the mobile file preview and thread feed as raw tags. No image element is ever created — this applies to external https: sources too, so it is a rendering capability gap, not a URL-resolution problem.
What #7857 already solves (and deliberately does not)
PR #7857 fixes workspace image URL resolution everywhere images already render: markdown-syntax images () now resolve through signed asset URLs on web and mobile (iOS native renderer and the JS fallback renderer), and web also covers raw HTML <img> because the web pipeline parses HTML. Mobile HTML rendering was explicitly scoped out of that PR as a separate capability.
What to look for
- The native parser already runs with
html: true— HTML arrives ashtml_block/html_inlinenodes carrying raw source text (apps/mobile/modules/t3-markdown-text). Nothing needs to change in the parser or native code. - A tree transform (same pattern as
nativeMarkdownWithPreservedSoftBreaks) that rewrites<img>tags inside those nodes into syntheticimagenodes gets the entire existing image pipeline for free —NativeMarkdownImage, therenderImageoverride, and the signed asset flow from #7857. The JS fallback can hook the same logic through anhtml_blockentry inCustomRenderers. - Suggested staging: (1)
<img>extraction only (~150–250 lines) — caveat: sibling HTML like the<h1 align="center">still shows as raw text, so blocks render half-fixed; (2) a safe-subset HTML normalizer (p/div/center/h1–h6/a/br/b/i→ equivalent markdown nodes) so HTML-headed READMEs render properly. Stage 2 carries the real design decisions (tag allowlist, attribute degradation likealign, nesting). - No sanitization puzzle on mobile: nothing executes — unknown tags simply remain text, so the allowlist is the safety boundary.
Related: SVG images in mobile markdown
Adjacent gap, worth fixing under this issue's umbrella: SVG sources in mobile markdown render as an empty frame because React Native's <Image> cannot decode SVG (external URLs included — this predates #7857, which deliberately excludes .svg from the signed-asset flow rather than fetch a URL the renderer cannot draw).
- The fix is small (~120–200 lines, no new dependency):
react-native-svgis already installed and exportsSvgUri. Remove the resolver's.svgexclusion, add anSvgUri-based branch in the two renderer hook points (createWorkspaceImageRenderer,createFallbackMarkdownImageRenderer), and passtextStylethrough therenderImagecontract so the SVG frame matches the module's default image frame and caption. - Caveat 1: extension detection covers workspace
.svgfiles but misses the highest-value case — badge URLs (shields.io) usually have no.svgsuffix and only reveal their type via content-type. Covering those needs sniffing or try-SvgUri-first logic; that is real design work beyond the simple version. - Caveat 2:
SvgUrifetches per mount with no cache — fine for file previews, worth attention in the thread feed given repaint/perf sensitivities.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/mobile/modules/t3-markdown-text, reading nativeMarkdownWithPreservedSoftBreaks, the html_block handling in CustomRenderers, and the createWorkspaceImageRenderer and createFallbackMarkdownImageRenderer entry points. Define the HTML allowlist and SVG behavior from the issue before changing the transform and renderer hooks; done means supported HTML renders as elements, images use the existing asset flow, and SVG images display without breaking feed rendering.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- markdown, react-native, typescript
- Domain
- frontend, mobile
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100