react-email icon indicating copy to clipboard operation
react-email copied to clipboard

[BUG] background image quoted url turned into html entities

Open haxxxton opened this issue 2 years ago • 24 comments
trafficstars

Some older email clients only resepect background image urls if the url is quoted (ie. background-image: url(./foo.jpg) will not work, but background-image: url("./foo.jpg") will). When using quoted urls in provided styles, the output from email export replaces either double quotes " or single quotes ' with html entities (" and ' respectively), breaking the inline style.

Steps to reproduce:

  • create a template with an inline style that contains a style that includes backgroundImage with a quoted url. eg. backgroundImage: "url('path/to/my/image.jpg')"
  • run email export
  • note that style is replaced with background-image: url('path/to/my/image.jpg')

haxxxton avatar Feb 04 '23 08:02 haxxxton

@zenorocha Can I work on this issue ? Can you guide me how to get started with this project ?

heysujal avatar Feb 05 '23 14:02 heysujal

Feel free to grab @heysujal

bukinoshita avatar Feb 06 '23 15:02 bukinoshita

@bukinoshita When I make a react-email-stater using npx create-email@latest then it keeps showing Generating emails preview and keeps loading. image image image image

Can you guide me how to go about fixing this issue once I run this in local ?

heysujal avatar Feb 08 '23 07:02 heysujal

@heysujal Can you try to place the react-email-starter-folder in a directory without spaces? Currently, the project is placed inside the New folder (2), I am guessing that the whitespaces in the path is the problem

bastiaanv avatar Feb 10 '23 11:02 bastiaanv

@bastiaanv thank you , I am able to run it my local system . Now, I am working to find a fix for the bug.

heysujal avatar Feb 13 '23 13:02 heysujal

@haxxxton I am able to reproduce the bug now. When the inline styles has url enclosed in double quote " like backgroundImage: 'url("http://localhost:3000/static/notion-logo.png")' then it does not produce any html entities. But if we use single quote ' for the url something like this backgroundImage: "url('http://localhost:3000/static/notion-logo.png')" then the single quotes are replaced by html entities. So, in my case I am only able to reproduce the bug when background image property is used in this way
backgroundImage: "url('http://localhost:3000/static/notion-logo.png')" . While this is a bug that need to be fixed it still doesn't affect the output for me as I am able to export email which is same in both cases. Let me know your thoughts on this.

heysujal avatar Feb 13 '23 14:02 heysujal

@heysujal , i dont find that myself. when i do something with double quotes i end up with html entities like " instead.

For example:

// input
<div style={{ background: `no-repeat center bottom/contain url("${baseUrl}/foo.jpg") #000` }} />
<!-- output -->
<div style="background:no-repeat center bottom/contain url(&quot;https://example.com/foo.jpg&quot;) #000000"

This then breaks the rendered output such that no background image is displayed

haxxxton avatar Feb 14 '23 01:02 haxxxton

I think the string template literal that you are using is causing the problem which I understand, it will be used when we have to use variables in a string. I only tested using simple quote outside url and double quote for enclosing the url which does not break the output. Now I will try to reproduce bug using template literal the way you mentioned in above comment.

heysujal avatar Feb 14 '23 05:02 heysujal

Would be great if anyone could help on this 🙏

bukinoshita avatar Feb 26 '23 20:02 bukinoshita

Would be great if anyone could help on this 🙏

@bukinoshita I asked for help in discord and explained my issue as well. Can you have a look again at my message if I give you the link

heysujal avatar Feb 26 '23 20:02 heysujal

Would be great if anyone could help on this 🙏

@bukinoshita I asked for help in discord and explained my issue as well. Can you have a look again at my message if I give you the link

Can you ping me there again, please? I probably missed. Or maybe we can add the case here as well so other people can related to the issue.

bukinoshita avatar Feb 26 '23 20:02 bukinoshita

my work around at the moment, is a second typescript step to post-process the built file output from react-email. let me know if you'd like a gist of it.. its not the most elegant.. but it works

haxxxton avatar Feb 26 '23 23:02 haxxxton

my work around at the moment, is a second typescript step to post-process the built file output from react-email. let me know if you'd like a gist of it.. its not the most elegant.. but it works

Would love to see so we can fix this, if you can share

bukinoshita avatar Feb 27 '23 00:02 bukinoshita

@bukinoshita @heysujal heres the fixer ts file. i have included how i run it, and my current package.json file. it basically just does regex replacements within the file

https://gist.github.com/haxxxton/1ae485b1896eed22d8f16808de696a02

haxxxton avatar Feb 28 '23 04:02 haxxxton

@heysujal Can you take a look that and maybe this should be part of the export command?

bukinoshita avatar Mar 01 '23 05:03 bukinoshita

@bukinoshita I am looking into it .My idea is to use unescape() function which is provided by typescript itself or else we can use lodash for the same. @haxxxton can we connect on discord as I am looking for help to fix this issue ? here is the discord thread https://discord.com/channels/1022242959736983613/1076557201482711180

heysujal avatar Mar 01 '23 12:03 heysujal

A similar bug was there in Signal App which I fixed. @bukinoshita I think we can use unescape function like I did here. But the only difficulty I am facing here is when I make a change in render package then how can I see if my changes are working ?

heysujal avatar Mar 02 '23 15:03 heysujal

A similar bug was there in Signal App which I fixed. @bukinoshita I think we can use unescape function like I did here. But the only difficulty I am facing here is when I make a change in render package then how can I see if my changes are working ?

Here's for reference https://github.com/resendlabs/react-email/issues/504. Let me know if that works

bukinoshita avatar Mar 03 '23 17:03 bukinoshita

@bukinoshita that didn't work for me. We need clear instructions on how to build the project in the local system.

heysujal avatar Mar 04 '23 14:03 heysujal

Yeah, you'll need to

  1. make the changes in the render component
  2. run yarn build to build the project
  3. yalc publish
  4. In a different project, run yalc add @react-email/render, check the package.json if it's referencing yalc package

bukinoshita avatar Mar 10 '23 17:03 bukinoshita

I may be mistaken, but I think this is a react-dom/server issue, not a react-email issue. The relevant issue is this one I think: https://github.com/facebook/react/issues/13838.

Though I might ask, in what context is the background-image style broken? Is there a particular email client that has a problem with it? I tried exploring some and found that an element with an inline style like this seemed to work fine in most contexts:

<div style="background-image:url(&#x27;https://www.iana.org/_img/2022/iana-logo-header.svg&#x27;)"></div>

It's not an email client, but I've created this JSFiddle to demonstrate that HTML entities should be cooperative for inline styles, but are not cooperative for <style> elements: https://jsfiddle.net/c7dxbset/

A reference to an old spec that supports this notion:

Please note that style sheet data that is element content may not contain character references, but style sheet data that is the value of an attribute may contain them. Basic HTML data types.

tdg5 avatar Jun 07 '23 17:06 tdg5

@nabby27 created a $50.00 reward using Opire

How to earn this reward?

Since this project does not have Opire bot installed yet 😞 you need to go to Opire and claim the rewards through your programmer's dashboard once you have your PR ready 💪

opiredev avatar May 02 '24 16:05 opiredev