Skip to content

Fix image srcset parsing #7702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

juliankrispel
Copy link

[lexical-playground] Feature: Add srcset support for image paste handling

Description

Currently, when pasting HTML content that contains images with srcset attributes instead of (or in addition to) src attributes, the Lexical image plugin fails to properly convert these images. This results in either:

  • Images not being converted at all
  • Images being created with empty src values
  • Images being ignored entirely

This PR adds comprehensive support for handling srcset attributes when pasting images into the Lexical editor. The solution includes:

Changes Made

  1. Created imageUtils.ts utility module with getImageSource() function that:

    • Intelligently extracts the best image source from an img element
    • Handles both src and srcset attributes
    • Supports various srcset formats (width descriptors, density descriptors, no descriptors)
    • Gracefully handles malformed srcset by falling back to src
    • Includes proper validation for image URLs including data URLs
  2. Updated image conversion functions:

    • Modified $convertImageElement in ImageNode.tsx
    • Modified $convertInlineImageElement in InlineImageNode.tsx
    • Both now use the shared getImageSource() utility function
  3. Added comprehensive testing:

    • Unit tests: 7 test cases covering all srcset scenarios
    • E2E tests: 7 test cases for real-world paste scenarios
    • All tests passing ✅

Features Supported

  • ✅ Width descriptors: srcset="image1.jpg 300w, image2.jpg 600w"
  • ✅ Density descriptors: srcset="image1.jpg 1x, image2.jpg 2x"
  • ✅ No descriptors: srcset="image1.jpg, image2.jpg"
  • ✅ Malformed srcset: Falls back to src attribute
  • ✅ Data URLs: Handles base64 encoded images in srcset
  • ✅ Mixed content: Works with text and images together
  • ✅ Multiple images: Handles multiple images with different srcset formats

Closes #

Test plan

Before

When pasting HTML content with images that have srcset attributes:

<img src="https://picsum.photos/300/200" 
     srcset="https://picsum.photos/300/200 300w, https://picsum.photos/600/400 600w" 
     alt="Responsive image" />

The image would either:

  • Not be converted at all
  • Be created with an empty src value
  • Be ignored entirely

After

The same HTML content now properly converts the image, extracting the appropriate source from the srcset attribute:

<span class="editor-image" contenteditable="false" data-lexical-decorator="true">
  <div draggable="false">
    <img alt="Responsive image" 
         draggable="false" 
         src="https://picsum.photos/300/200"
         style="height: inherit; max-width: 500px; width: inherit" />
  </div>
</span>

Test Coverage

  • Unit Tests: 7/7 passing ✅

    • srcset with width descriptors
    • srcset with density descriptors
    • srcset without descriptors
    • malformed srcset (falls back to src)
    • data URLs in srcset
    • mixed content with images
    • multiple images with different formats
  • E2E Tests: 7 test cases created for real-world paste scenarios

    • All test cases properly validate the converted HTML output
    • Tests cover various srcset formats and edge cases

Copy link

vercel bot commented Jul 18, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
lexical ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 18, 2025 9:08am
lexical-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 18, 2025 9:08am

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 18, 2025
@ivailop7 ivailop7 added the extended-tests Run extended e2e tests on a PR label Jul 18, 2025
@etrepum
Copy link
Collaborator

etrepum commented Jul 18, 2025

If the goal here is to support srcset, why not add srcset to the ImageNode model instead of trying to downgrade srcset by parsing it as src?

@vadimkantorov
Copy link

vadimkantorov commented Jul 25, 2025

Maybe some downgrade is only needed for exporting to Markdown...


Another related useful feature to src parsing/formatting I used (and would be great to have more support for it in stock ImageNode) is specifying an url-prefix for the ImageNode (e.g. ImageNode.url_prefix = "https://mydomain.com/myblog/"), this prefix should be prepended when rendering the node to WYSIWYG (so that <img src="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/images/myimage.jpg">...</img> is correctly parsed/displayed, as well as ![my](/images/myimage.jpg)). And when the image node is exported back to HTML/Markdown, this image prefix is to be stripped. This simple hack worked.

This is useful to keep the markdown/html lean and manage the images prefix via the SSG configuration.

@etrepum
Copy link
Collaborator

etrepum commented Jul 27, 2025

Downgrading the model of components because Markdown might not support some feature isn't really something that makes sense in the general case. You could always do the downgrade during markdown export.

@vadimkantorov
Copy link

vadimkantorov commented Jul 28, 2025

Exactly, I'm of course proposing to move the downgrader from this PR into the ImageNode markdown exporter code

@juliankrispel
Copy link
Author

If the goal here is to support srcset, why not add srcset to the ImageNode model instead of trying to downgrade srcset by parsing it as src?

Technically I like the idea but how is that useful in a real-world context? Afaik srcset is typically generated serverside, as it's too much configuration for a user to bother with.

@etrepum
Copy link
Collaborator

etrepum commented Aug 4, 2025

Anyone using images in a properly written rich text editor will have server-side code involved to handle image uploads, why wouldn't it support srcset?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants