fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(web/mobile): render project images in nested markdown file previews and harden markdown images - #7857

Closed
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path
Closed

fix(web/mobile): render project images in nested markdown file previews and harden markdown images#7857
flamboh wants to merge 13 commits into
pingdotgg:mainfrom
flamboh:t3code/fix-readme-image-path

Conversation

@flamboh

@flambohflamboh commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

The problem

  • fix: render workspace images in chat markdown #6433 fixed workspace images in chat markdown. File previews still resolve relative images against the project root instead of the previewed document path. This meant that markdown files at the project root would render images properly, by coincidentally always checking cwd, but images in nested markdown files like docs/README.md would fail.
  • This PR also fixes sizing and alignment issues in the PR viewer with markdown images.
  • mobile file previews don't render workspace images at all, and several src shapes die before the resolver runs.

The solution

  • Use fix: render workspace images in chat markdown #6433's renderImage wiring for the file sidebar, resolving images based on the location of the document
  • The current ThreadFeed architecture for chat markdown images is moved into a shared markdownImages.tsx to allow file previews and chat to use the same code paths
  • This PR also makes it so inline styling rendering is handled correctly, an image with width/height=128 renders at 128x128 in file previews and snippets like <p align="center"> are centered
  • Remove bottom-alignment from PR viewer images so they are aligned the same as on GitHub

Hardening

  • Windows drive paths get stripped before the resolver ever runs. This PR addresses that.
  • SVG view fragments like icon.svg#logo would drop the #logo part and never re-append it, changing the client-side rendering
  • Mobile fetched SVGs it couldn't draw
    • Mobile currently cannot render SVGs, so instead of fetching them when they can't even display, this PR guards against fetching them
  • Copying text with a markdown image would drop the image
    • The clipboard serializer included the expiring asset URL, instead of the original markdown copy.

UI Changes

Below is the relevant HTML snippet for the desktop screenshots, with the favicon at public/icon-512.png for the root, and tests/public/icon-512.png for the nested examples:

<div>
<p align="center">
<img src="public/icon-512.png" alt="" width="128" height="128" />
</p>
<h1 align="center">Tagium</h1>
<p align="center">
Local, lossless metadata editing for MP3, FLAC, M4A, and Opus audio files. <br>
Bring your favorite tracks anywhere you listen.
<br />
<a href="https://tagium.app">tagium.app</a>
</p>
</div>

Web Before, nested readme

Fails to find images, is checking the wrong directory

SCR-20260822-mwzi

Web Before, root dir readme

Ignores image height styling

SCR-20260822-ndfd

Web After

Now renders at all and at the correct size.

SCR-20260822-nbpp

PR Viewer before

image

PR Viewer after (now identical to GitHub's rendering)

image

Mobile UI changes

Here's the markdown for the below example:

# Workspace images in markdown
Relative image paths now resolve through signed asset URLs on iOS.
![Workspace-relative: apps/web/public/apple-touch-icon.png](apps/web/public/apple-touch-icon.png)
![External URL (control)](https://raw.githubusercontent.com/github/explore/main/topics/typescript/typescript.png)

iOS Before

ios-workspace-images-before

iOS After

ios-workspace-images-after

Scope Notes

  • Mobile doesn't really render HTML at all right now, so I treated that as a separate out-of-scope issue.
  • React Natives <Image> cannot decode SVGs at all, so SVGs show image not found.

The two above capability gaps are tracked in #7929

Review

  • This could probably use a review from someone on an android client

Built with Fable 5 and GPT 5.6 Sol in T3 Code

Note

Render project images in FileMarkdownPreview and harden markdown images

  • Resolves workspace-relative images in FileMarkdownPreview relative to the markdown document directory using signed asset URLs.
  • Adds rehypePreserveWindowsImageSrc and isWindowsDrivePathHref to keep Windows drive path image sources through sanitization.
  • Uses authoredImageSizeStyle to apply authored width and height as inline CSS while respecting chat layout bounds.
  • Retains SVG fragments on signed URLs with markdownImageSourceFragment and copies the original markdown source on image selection.
  • Risk: SVG images in mobile markdown render an unavailable placeholder instead of loading; check the .svg guard in markdownImages.tsx.

Macroscope summarized f632e92.

@coderabbitai

coderabbitaiBot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cd695e75-8500-41a0-b420-80cef0d58105

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 22, 2026
@flambohflamboh changed the title fix(web): render workspace-relative images in markdown previewsfix(web): render project images in markdown previewsAug 22, 2026
Comment threadapps/mobile/src/features/files/ThreadFilesRouteScreen.tsx Outdated
Comment threadapps/web/src/markdown-links.ts Outdated
Comment threadapps/web/src/markdown-links.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the web markdown image path: workspace images now render a signed asset URL as src, which changes what the existing copy-as-markdown serializer emits. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from f664077 to 2393f5cCompareAugust 22, 2026 20:26
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web): render project images in markdown previewsfix(web/mobile): render project images in markdown previewsAug 22, 2026
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from ad2e233 to f3fab02CompareAugust 22, 2026 21:09
@flambohflamboh changed the title fix(web/mobile): render project images in markdown previewsfix(web/mobile): render project images in file markdown previewsAug 22, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding: the workspace-image loading placeholder now receives authored pixel dimensions but lacks the height/width caps the loaded image has, so oversized authored sizes can overflow the container and cause a large layout jump on load.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new authored-dimension inline sizing in apps/web/src/components/ChatMarkdown.tsx: applying width and height as independent fixed pixel values lets the shared max-h/max-w caps clamp each axis separately, which breaks the authored aspect ratio for both-dimension images. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing added to ChatMarkdown: the both-axes branch still lets max-h-[30rem] reshape the box for tall images.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One remaining copy-fidelity inconsistency in the image renderer; the authored-size and signed-URL/copy handling for workspace images now looks correct (the min(100%, 30rem, ratio) width cap keeps the placeholder and the loaded image on the same proportional bounds).

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 178056e to 0f23290CompareAugust 23, 2026 01:36
@github-actionsgithub-actionsBot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Aug 23, 2026

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new inline layout for workspace markdown images: the loading skeleton's geometry no longer matches the inline flow the same change introduces.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previewsfix(web/mobile): render project images in file markdown previews and harden markdown imagesAug 23, 2026
@flamboh
flamboh marked this pull request as ready for review August 23, 2026 02:02
@flamboh
flambohforce-pushed the t3code/fix-readme-image-path branch from 923ad27 to 2727cdcCompareAugust 23, 2026 10:07

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two layout findings on the new inline image handling in ChatMarkdown.tsx. Everything else (copy parity across all three image states, ratio-aware sizing for fully sized images, bounded placeholder width) looks consistent.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the authored image sizing helper in apps/web/src/components/ChatMarkdown.tsx. The both-axes case is now ratio-correct, but the single-axis case (the common README form) still loses the intrinsic ratio.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

@t3dotgg

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

Closing this PR after an automated pass over open pull requests. Workspace image rendering already shipped in #6433.

@t3dotggt3dotgg closed this Aug 23, 2026
@Bil0000

Copy link
Copy Markdown
Contributor

@t3dotgg This builds on top of #6433

@flambohflamboh changed the title fix(web/mobile): render project images in file markdown previews and harden markdown imagesfix(web/mobile): render project images in file nested markdown previews and harden markdown imagesAug 23, 2026
@flamboh

Copy link
Copy Markdown
ContributorAuthor

Bilal is correct. At minimum, any markdown file not in the root directory is broken and will not display images that are linked to relatively.

e.g.

tests/README.md
and
tests/public/icon.png

with an image relatively linked to by public/icon.png

will show "image not available"

@flambohflamboh changed the title fix(web/mobile): render project images in file nested markdown previews and harden markdown imagesfix(web/mobile): render project images in nested markdown file previews and harden markdown imagesAug 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL500-999 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@flamboh@t3dotgg@Bil0000