payloadcms / payload

Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
https://payloadcms.com
MIT License
24.87k stars 1.58k forks source link

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

Open marpstar opened 2 months ago

marpstar commented 2 months ago

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

lorenzrabs commented 2 months ago

I'm having the same issues. Even with the Image Component from next i'm not able to display SVGs. Removal of "<?xml version="1.0" encoding="utf-8"?>" fixes the issue for me aswell.

theo-lubert commented 1 month ago

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

theo-lubert commented 1 month ago

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