resend / react-email

💌 Build and send emails using React
https://react.email
MIT License
14.03k stars 636 forks source link

Some email clients don't display background color on <Body> (including Outlook, and others) #662

Open magoz opened 1 year ago

magoz commented 1 year ago

Describe the Bug

The README of the<Body> component states that you can use it to set the email background color and that is supported by the most popular email clients.

But Outlook, and other clients, ignore the background color set on the <Body>.

I've realized that the <Body> component is not listed in React Email docs but is used by all the examples.

Is this a known issue? If so, how should we go around it?

Screenshot 2023-04-25 at 20 29 21 Screenshot 2023-04-25 at 19 37 58 Screenshot 2023-04-25 at 19 37 48 Screenshot 2023-04-25 at 19 38 15 Screenshot 2023-04-25 at 19 38 27

Which package is affected (leave empty if unsure)

No response

Link to the code that reproduces this issue

https://demo.react.email/preview/codepen-challengers

To Reproduce

Send an email from the demo to an Outlook email address.

The email will not display the background color.

Expected Behavior

The background color set on is displayed by all email clients.

What's your node version? (if relevant)

No response

edenstrom commented 1 year ago

For now we're using our own component for this which works great for us.

import { Body } from "@react-email/components";

export type EmailBodyHackProps = {
  children?: React.ReactNode;
  style?: React.CSSProperties;
};

export const EmailBodyHack = ({ children, style }: EmailBodyHackProps) => {
  return (
    <Body>
      <table width="100%" style={style}>
        <tbody>
          <tr style={{ width: "100%" }}>
            <td>{children}</td>
          </tr>
        </tbody>
      </table>
    </Body>
  );
};

Tested in outlook.com but not native Outlook yet.

Note: Naming is hard 😅

magoz commented 1 year ago

Perhaps <Body> should implement something like this internally? @bukinoshita

bukinoshita commented 1 year ago

Yes, let's get this fixed.

jinsley8 commented 1 year ago

For now we're using our own component for this which works great for us.

import { Body } from "@react-email/components";

export type EmailBodyHackProps = {
  children?: React.ReactNode;
  style?: React.CSSProperties;
};

export const EmailBodyHack = ({ children, style }: EmailBodyHackProps) => {
  return (
    <Body>
      <table width="100%" style={style}>
        <tbody>
          <tr style={{ width: "100%" }}>
            <td>{children}</td>
          </tr>
        </tbody>
      </table>
    </Body>
  );
};

Tested in outlook.com but not native Outlook yet.

Note: Naming is hard 😅

The Container code is fairly similar if not the same as the code you posted except it has a max-width which can be overridden: https://github.com/resendlabs/react-email/blob/main/packages/container/src/container.tsx

I tried similar using <Container> with max-width set to none. It works great on the Gmail browser client but not on Apple Mail or Gmail iOS app.

<Body style={main}>
    // Added this next line
    <Container style={{ backgroundColor: '#0F1217', width: '100%', maxWidth: 'none' }}> 
        <Container style={container}>
            {... the rest of template code}
        </Container>
    </Container>
</Body>
ZeldOcarina commented 1 year ago

Confirming this bug on Outlook. Trying the hack by @edenstrom.

ZeldOcarina commented 1 year ago

No luck with the hack on Outlook.. :(

rbestardpino commented 11 months ago

Faced the same issue and none of the solutions above worked for me.

What I ended up doing is also applying the styles to the html body on a style tag inside the Head component:

<Head>
    <style>
      {`
        body {
          background-color: #F2F2F2;
          margin: auto;
          padding: 32px 24px;
          font-family: sans-serif;
        }
      `}
    </style>
</Head>

Full code diff

Previously (didn't work):

import React from "react";
import {
  Body,
  Container,
  Head,
  Html,
  Img,
  Preview,
  Tailwind,
  Text,
} from "@react-email/components";

import tailwind from "@tailwind-config";

interface Props {
  children: React.ReactNode;
  previewText?: string;
}

export default function TemplateBase({ previewText, children }: Props) {
  return (
    <Html lang="en">
      <Head />
      {previewText && <Preview>{previewText}</Preview>}
      <Tailwind config={tailwind}>
        <Body className="mx-auto my-auto bg-[#F2F2F2] px-6 py-8 font-sans">
           ...
        </Body>
      </Tailwind>
    </Html>
  );
}

Currently (works):

import React from "react";
import {
  Body,
  Container,
  Head,
  Html,
  Img,
  Preview,
  Tailwind,
  Text,
} from "@react-email/components";

import tailwind from "@tailwind-config";

interface Props {
  children: React.ReactNode;
  previewText?: string;
}

export default function TemplateBase({ previewText, children }: Props) {
  return (
    <Html lang="en">
      <Head>
        <style>
          {`
            body {
              background-color: #F2F2F2;
              margin: auto;
              padding: 32px 24px;
              font-family: sans-serif;
            }
          `}
        </style>
      </Head>
      {previewText && <Preview>{previewText}</Preview>}
      <Tailwind config={tailwind}>
        <Body>
          ...
        </Body>
      </Tailwind>
    </Html>
  );
}

I had to keep both the style tag and the inline styles becase on gmail it works only with the inline styles and on outlook only with the style tag.

I tested it in both Gmail and Outlook and, although I believe does not make a difference, using both resend and AWS SES with the render method. Every combination worked

ZeldOcarina commented 11 months ago

Thanks @rbestardpino. I feel this is still an issue though as the purpose of the framework is to normalize HTML quirks between browsers etc. and needing to go through hacks to style the background is sub-optimal imo

jinsley8 commented 11 months ago

@ZeldOcarina There are limitations to some email clients that just can't be changed but I agree it would be good to at least list those limitations in docs so users are aware.

Email preview testing software like Litmus and Email on Acid start at $99/mo so most user would not have the ability to check if their emails aren't rendering correctly.

Here are email previewer services to help test your designs across clients. I haven't tried the free ones yet so I don't know how accurate they are:

Free: https://putsmail.com/ https://inboxanalyzer.io/features https://emailpreview.io/

Paid: https://www.litmus.com/ https://www.emailonacid.com/ https://emailpreviewservices.com/en/features/email-design-testing https://mailosaur.com/email-testing https://www.sendforensics.com/features/client-previews/

timothyjoh commented 10 months ago

Other libraries like Mailing and Maizzle use https://github.com/Automattic/juice to do the automatic conversion of CSS classes to inline styles. You should adopt this.

missbruni commented 10 months ago

Do we have a fix coming for this?

endymion1818 commented 5 months ago

Chiming in here, this is a nuisance. To get around both Outlook and Gmail, and to still not ruin it for other clients, I had to specify the CSS for the background twice, and remove it from the <Body> tag.

shahneil commented 1 month ago

Any updates?