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

<Preview> results in poor results in Gmail

Open ui-mattlucas opened this issue 9 months ago • 0 comments

Describe the Bug

I'm using the Preview tag in the prescribed way:

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

interface LayoutProps {
  children?: ReactNode;
}

import { headContent } from "./context";
import Footer from "../Footer";

export default function Layout({ children }: LayoutProps) {
  return (
    <Html style={{ backgroundColor: "black" }}>
      <Tailwind>
        <Head>{headContent()}</Head>
        <Body
          style={{ margin: 0, padding: 0 }}
          className="font-lato bg-black text-white min-w-full"
        >
          <Preview>*|MC_PREVIEW_TEXT|*</Preview>
          <Container className="m-auto">
            {children}
            <Footer />
          </Container>
        </Body>
      </Tailwind>
    </Html>
  );
}

When I send out the resulting html, there is a gap between the subject line and the preview text.

Additionally, the email content will run up against the Preview text on the other side resulting in a somewhat mangled marketing experience.

This could perhaps be a change to Gmail because I didn't see it before, but it certainly will affect a lot of users on both sides.

Through experimentation, I believe that a better experience may be acquired by jettisoning the

tags in the Preview component and instead rendering a table with the Preview string like this:
```
<Body>
      <table
        role="presentation"
        width="100%"
        cellPadding="0"
        cellSpacing="0"
        style={{
          display: "none",
          height: 0,
          maxHeight: "0px",
          overflow: "hidden",
        }}
      >
        <tr>
          <td
            style={{
              fontSize: "1px",
              lineHeight: "1px",
              color: "#000000",
              opacity: "0",
            }}
          >
            {/* BUG: Whitespace is needed so Gmail doesn't include other email text after preview */}
            *|MC_PREVIEW_TEXT|*
            <span
              dangerouslySetInnerHTML={{
                __html: "&zwnj;&nbsp;".repeat(100),
              }}
            />
          </td>
        </tr>
      </table>
      <Container className="m-auto">


### Which package is affected (leave empty if unsure)

@react-email/preview

### Link to the code that reproduces this issue

https://codepen.io/Matt-Lucas-the-solid/pen/OPJpQGx

### To Reproduce

With the Preview tags:
<img width="1333" alt="Image" src="https://github.com/user-attachments/assets/a3109d23-943d-4bc1-b3dc-6ac6f2abae3a" />



### Expected Behavior

With the Table:
<img width="1324" alt="Image" src="https://github.com/user-attachments/assets/1bf955d4-e85a-41b4-9a53-70343ad7ad43" />


Perhaps the Preview component should be rewritten to export a Table instead of using the divs if block elements create unnecessary empty space?

### What's your node version? (if relevant)

22.13.1

ui-mattlucas avatar Mar 03 '25 21:03 ui-mattlucas