feat: render loading placeholder for incomplete streaming images - #504
Conversation
|
@sleitor is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
farnabaz
left a comment
There was a problem hiding this comment.
Thanks for the PR @sleitor
Do you mind removing line numbers commit from this PR?
Also I do think streamdown schema will be blocked by rehype-harden package we need to change placeholder to another text. maybe even an 1x1 pixel placeholder
data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"/>
// or equivalent png
Incomplete images during streaming (e.g. ` now render an animated skeleton placeholder instead of being silently removed. Changes: - remend: emit `` for incomplete images instead of stripping them entirely, in both handleIncompleteUrl() and handleIncompleteText() - remend: add earlyReturn check for `streamdown:incomplete-image` marker - streamdown: ImageComponent renders animate-pulse skeleton div when src === 'streamdown:incomplete-image' - Tests updated to reflect new placeholder behavior Mirrors the existing incomplete link handling (streamdown:incomplete-link). Closes vercel#503
Replace the streamdown:incomplete-image custom-scheme marker with a 1x1 transparent PNG data: URI. Non-http(s)/data URL schemes can be stripped by strict URL-sanitizing rehype/remark plugins (e.g. rehype-harden), which would prevent the placeholder from ever reaching the ImageComponent's src check. Addresses review feedback from @farnabaz on vercel#504.
44ea6a3 to
4a07096
Compare
|
Thanks for the review, @farnabaz!
All 356 remend + 951 streamdown tests pass, lint is clean. Let me know if you'd like a different data URI (e.g. transparent GIF/SVG) or any other adjustments. |
# Conflicts: # packages/streamdown/__tests__/image.test.tsx
Replace the shared 1x1 PNG data URI marker with streamdown:incomplete-image (link parity). Allowlist the streamdown protocol on img src in the default sanitize schema so the sentinel survives rehype-sanitize + rehype-harden, and add coverage that mirrors incomplete-link sanitize tests.
|
Thanks @sleitor, |
Summary
Fixes #503 — incomplete images during streaming now render an animated skeleton placeholder instead of being silently removed. This mirrors the existing behavior for incomplete links.
What changed
link-image-handler.ts: BothhandleIncompleteUrl()andhandleIncompleteText()now emitfor incomplete images instead of stripping them entirelyindex.ts: UpdatedearlyReturncheck to also short-circuit onstreamdown:incomplete-image; fixed JSDoc forimagesoptionpackages/streamdownlib/image.tsx:ImageComponentdetectssrc === 'streamdown:incomplete-image'and renders ananimate-pulseskeleton div withdata-incomplete="true"Changeset:
remend@patch+streamdown@patchBefore / After
Before:
After:
![logo](./assets/log→ animated grey skeleton placeholder shown until the stream completesTest coverage
All existing tests updated; 4 new tests added for the placeholder behavior.