Skip to content

feat: render loading placeholder for incomplete streaming images - #604

Closed
farnabaz wants to merge 4 commits into
mainfrom
feat/incomplete-image-placeholder
Closed

feat: render loading placeholder for incomplete streaming images#604
farnabaz wants to merge 4 commits into
mainfrom
feat/incomplete-image-placeholder

Conversation

@farnabaz

@farnabaz farnabaz commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Replaces / continues #504 (fork PR — no push access to sleitor/streamdown).

Summary

  • Incomplete images during streaming render an animated skeleton instead of being stripped
  • Marker is streamdown:incomplete-image (parity with incomplete links), not a shared 1×1 PNG data URI
  • Default sanitize schema allowlists streamdown on img[src] so the sentinel survives rehype-sanitize + rehype-harden
  • Merged main, conflict fixed in image.test.tsx
  • Closes Streaming support for partial images (similar to incomplete link handling) #503

Test plan

  • pnpm test in remend + streamdown
  • CI green

sleitor and others added 4 commits August 30, 2026 17:02
Incomplete images during streaming (e.g. `![alt](https://exampl`) now
render an animated skeleton placeholder instead of being silently removed.

Changes:
- remend: emit `![alt](streamdown:incomplete-image)` 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 #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 #504.
# 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.
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
streamdown Ready Ready Preview, v0 Sep 1, 2026 10:43am UTC

@vercel vercel Bot 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.

Additional Suggestion:

In linkMode: "text-only", disabling the links handler's earlyReturn lets later formatting handlers append stray closing markers after the incomplete-image sentinel, corrupting output.

Fix on Vercel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming support for partial images (similar to incomplete link handling)

2 participants