payload icon indicating copy to clipboard operation
payload copied to clipboard

Uploaded SVGs with <?xml /> tag fail to load on page

Open marpstar opened this issue 1 year ago • 6 comments

Link to reproduction

No response

Payload Version

3.0.0-beta.73

Node Version

22.6.0

Next.js Version

15.0.0-rc.0

Describe the Bug

Recently upgraded my project to 3.0 beta. Noticed that SVG images being served by Payload are not loading correctly on my page.

If I hit the URL directly in the address bar, it works fine. Seems to be an issue only when using image tags?

Payload returns 200, Safari will actually let you inspect the DOM of the returned SVG, but it won't show an image preview.

Chrome says that no data was returned but the Content-Length response greater reflects the size of the expected SVG.

I noticed a comment on Discord that mentions similar SVG problems. This person found that removing <?xml version="1.0" encoding="utf-8"?> from the SVGs fixed the issue. My results are consistent -- removing that line results in the SVG loading without issue.

Reproduction Steps

  1. Upload an SVG containing the line <?xml version="1.0" encoding="utf-8"?> at the top to a Payload collection.
  2. Use an <img /> tag with the src set to the file URL.
  3. Notice that the image fails to load on the page.
  4. Remove <?xml version="1.0" encoding="utf-8"?> from the SVG file
  5. SVG file loads without issue

Adapters and Plugins

No response

marpstar avatar Aug 11 '24 15:08 marpstar

I'm having the same issues. Even with the Image Component from next i'm not able to display SVGs. Removal of "" fixes the issue for me aswell.

lorenzrabs avatar Aug 26 '24 08:08 lorenzrabs

The media is saved with mimeType "image/svg+xml", but is served as content-type: application/xml (/api/media/file/<img>.svg)

theo-lubert avatar Sep 04 '24 13:09 theo-lubert

This is due to the package file-type not supporting SVGs

(cf. https://www.npmjs.com/package/file-type)

This package is for detecting binary-based file formats, not text-based formats like .txt, .csv, .svg, etc.

It might not be an easy fix. It is worth mentioning that @payloadcms/storage-s3 does not have that issue (same goes with @payloadcms/plugin-cloud-storage if you're not on Payload 3.0 just yet).

Most production apps won't use on-disk storage anyway. And you can very easily have a Minio running locally if can't use an actual S3 bucket.

Blog post about Cloud storage: https://payloadcms.com/blog/plugin-cloud-storage

theo-lubert avatar Sep 05 '24 14:09 theo-lubert

I hacked around this bug by adding this config to my media collection:

  upload: {
    modifyResponseHeaders({ headers }) {
      if (headers.get('content-type') === 'application/xml') {
        headers.set('content-type', 'image/svg+xml; charset=utf-8')
      }
      return headers
    },

This might be available on v3 only, not sure about that.

linobino1 avatar Nov 06 '24 07:11 linobino1

@linobino1 Nice fix.

I'm guessing that it makes SVG work by breaking other XML files though. Uploads are mostly used for images, so it fixes the main use case, but it might not be clean enough to be merged.

You can still use this if your use case is image-only uploads (so most apps I would assume).

theo-lubert avatar Nov 13 '24 13:11 theo-lubert

I also ran into this.

Using a plugin "fixed" it for me.

Thanks, @theo-lubert.

danielkoller avatar Dec 10 '24 18:12 danielkoller

Yes same issue here, accessing the image url in the browser works fine, but curling it returns content-type: application/xml instead. @linobino1 fix works for my development environment, I'm using cloud storage only in production.

Twansparant avatar Jan 20 '25 10:01 Twansparant

I saw that the upload logic has a specific condition to handle this,

https://github.com/payloadcms/payload/blob/8ace0cab339815627b48f43ee952684f04889ca6/packages/payload/src/uploads/generateFileData.ts#L206-L209

Perhaps we can also add one in the download logic.

https://github.com/payloadcms/payload/blob/8ace0cab339815627b48f43ee952684f04889ca6/packages/payload/src/collections/endpoints/getFile.ts#L58-L61

blueset avatar Feb 03 '25 05:02 blueset

I am having the same issue

yeseniamolinab avatar Mar 17 '25 16:03 yeseniamolinab

Hi, any news?

manudicri avatar May 09 '25 18:05 manudicri

+1

akaJuliaan avatar May 13 '25 08:05 akaJuliaan

Removing the xml tag fixes it for me too.. I guess a custom middleware that removes the tag would be perfect, but I'm new with payload so I don't know if it's possible

manudicri avatar May 13 '25 09:05 manudicri

This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.

github-actions[bot] avatar Aug 02 '25 05:08 github-actions[bot]