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

Tailwind classes rendered in head don't get forwarded

Open mckelveygreg opened this issue 1 year ago • 9 comments

  • Component or Package Name: Tailwind
  • Component or Package Version: 1.7.0
  • @jsx-email/cli Version?: 3.0.1
  • Operating System (or Browser): osx
  • Node Version: 20.10
  • Link to reproduction (⚠️ read below): N/A
  • Link to previous PR where this was fixed: https://github.com/resend/react-email/pull/629

Expected Behavior

Tailwind styles are converted to inline styles unless they have media queries.

Actual Behavior

All tailwind ends up in the head, so forwarded emails won't have original styling.

Additional Information

When using react-email last year, I ran into the problem where my designer excited forwarded me the email template I made, only for me to find out that the head (and styles) doesn't get forwarded!

For development, I decided to do the templates Mobile first, and any responsive css would then end up in the head (that is the only place for media queries). This resulted in an email that could be mobile or desktop, but would fallback to mobile if forwarded / resent anywhere else.

For our emails, it is very important that they can be sent, resent, and maintain at least a mobile fallback.


I poked around UnoCSS to see if they have a similar tw-to-css function, and I wasn't able to find anything. Perhaps we could add that as a transformer, but I'm unfamiliar with the lib.


I made a very quick example of an example email, and then I forwarded it to show that the tailwind colors didn't come along:

Original: image

Forwarded: image

Perhaps I could be of more help if I could be pointed in a good direction as well! Excited to be able to move to jsx-email and keep contributing

mckelveygreg avatar Jan 06 '24 00:01 mckelveygreg

Hey thanks for opening an issue and the kind words. We actually looked at a similar thing when we were debugging some issues with gmail styles in classes in

as well. What we arrived on was using https://github.com/posthtml/posthtml-inline-css. tw-to-css is a great project but just isn't efficient enough for the speed we wanted to achieve.

We ended up finding a better way around the issues we were triaging (hashing class names and replacing css vars). posthtml is an interesting project, they aim to be postcss for html. posthtml-inline-css worked well in demos, but getting it to bundle correctly for our preview app (and anyone else wanting to bundle templates) was a hard slog - it's just not meant to be bundled. That said, it could be a really great post-processing tool for you, if you're running something serverside or in a worker. (It's worth noting that my interaction with the lead maintainer of that project was not positive)

What we do use internally is https://github.com/rehypejs/rehype, which is also an html processing package, and bundles quite nicely. While it doesn't have anything premade to handle this, I wouldn't be opposed to including a plugin for rehype that processed CSS in <head> and <style> tags and inlined it. The one warning I have for you about that is - the size of the email will explode. One great benefit to jsx-email over react-email is the size of the output, especially with tailwind. It can be as much as 10x smaller because we don't inline the tailwind css into style attributes. If you were up for trying your hand at a rehype plugin, we could include an inlineCss option for the render method that would run your plugin as part of processing.

Hope all that made sense 😄

shellscape avatar Jan 06 '24 00:01 shellscape

I did find this https://github.com/tani/rehype-inline-css which would be a good basis. It's using an outdated css package that doesn't support modern css and would probably swap that out for postcss, but it's a start.

shellscape avatar Jan 11 '24 03:01 shellscape

Having this same issue — just to summarize / make sure my understanding of the current status is right:

  • Tailwind-based emails break when forwarded (or put in a reply)
  • There is no current workaround that allows continuing to use Tailwind, the "rehype plugin" idea above is suggested as a possible change to jsx-email itself that might allow a workaround via exposing an inlineCss option in render which would allow us to make the trade off of bloating the email size but getting Tailwind emails to be forward-able
  • The best path forward today if I need my emails to be fowardable is to rewrite them without Tailwind at all

grahamplace avatar Mar 09 '24 01:03 grahamplace

@grahamplace not entirely.

Gmail (and it seems limited to Gmail) strips <head> tags when forwarding (and it's selective about replies).

The current workaround is to use the rehype plugin linked to above - for usage, reference this https://github.com/rehypejs/rehype?tab=readme-ov-file#what-is-this and expand Show example code. And that rehype plugin works very well.

If Tailwind accelerates your development and makes maintenance easier, I would suggest introducing an additional step that ran the html from jsx-email through that rehype plugin. The next major version of jsx-email is in development and will provide an internal option to inline the css, but it requires some breaking changes we can't introduce to the 1.x.x version.

shellscape avatar Mar 09 '24 01:03 shellscape

So I seem to be needing to put important infront of all of my text styles I don't know if this is related?

Perhaps the compiler could automatically make all tailwind styles important or reset the base style sheet?

samducker avatar Mar 25 '24 12:03 samducker

@samducker you should be able to use? disableDefaultStyle. https://jsx.email/docs/components/hr#component-props

(but yeah that's unrelated to this issue)

shellscape avatar Mar 25 '24 12:03 shellscape

I've got a solution for the forwarded emails in mind, and I'll be working on that over the next week. What I have in mind will be in the next v2.0.0 preview.

shellscape avatar Apr 02 '24 01:04 shellscape

Just wrapped up work on a new hooks system to allow for this. More to come...

shellscape avatar Apr 08 '24 03:04 shellscape

I've implemented a new plugin for the next release that inlines CSS which will effectively resolve this issue. I just can't close this until we release that new version. Still a bunch to wrap up on that before we can.

shellscape avatar May 09 '24 12:05 shellscape

v2.0.0 PR is up https://github.com/shellscape/jsx-email/pull/206 and contains a plugin to inline css, which will take care of the problems outlined in this issue. We're converting our docs site from vitepress over to astro, and following that we'll have a full page dedicated to the lifecycle hooks and the core plugins.

shellscape avatar Sep 14 '24 21:09 shellscape