Quiz - Authoring templates
You need a two-column header — logo on the left, a “Open dashboard” link on the right. You write it with <div className="flex justify-between">, and it looks perfect in the preview server. Why is this still the wrong call?
flex; Gmail discards it and collapses the two columns into one stack. Use <Row> and <Column>, which compile to the table layout every client understands.flex works in every client, but <div> is disallowed in React Email templates — you must use <Section> as the outer wrapper for the styles to inline.<Tailwind> component would throw a build error on flex, so the template never compiles.flex looks aligned there, then Gmail throws the flex away and stacks everything into one column with no warning. Horizontal layout in email is <Row> plus <Column>, which emit table cells. <div> itself is fine, and <Tailwind> doesn’t error on unsupported utilities — it silently drops them, which is exactly why the failure is so easy to miss.Your brand color is defined in the web app as an OKLCH value in a Tailwind v4 @theme block. What has to happen for it to render reliably on a <Button> across mailbox clients?
emailTailwindConfig) as a hex value, because some clients can’t parse OKLCH and silently drop the whole background-color, leaving the button with no fill.@theme block to <Tailwind>’s config prop so the same OKLCH tokens are reused without duplication.<Tailwind> converts OKLCH to a client-safe color space automatically at render time.<Tailwind> component is configured through a JS object, not a CSS @theme block, so the web tokens can’t be reused directly. And a client that can’t parse OKLCH doesn’t fall back gracefully — it drops the property entirely, so the brand button renders with no background. The fix is a hand-maintained config mirroring each token as hex, which renders everywhere.A teammate inlines the logo as a base64 data URL so there’s “nothing to host.” Beyond the image possibly not appearing, what’s the more serious consequence?
width/height attributes, not base64.Which lines belong inside a WelcomeEmail template, and which belong in the Server Action that calls it? Select every statement that’s correct.
firstName and verifyUrl from props belongs inside the template — it’s pure presentation.verifyUrl from process.env.APP_URL and a token belongs in the Server Action, not the template.if preview / else production branching anywhere.The preview server’s dark-mode toggle shows your template looking clean in dark mode. What can you correctly conclude?
prefers-color-scheme: dark and can’t reproduce Gmail Android’s blanket inversion. Confirm with a real test-send.You’re about to declare a template done. Order matters: which check sits last in the loop, and why isn’t it just another preview pass?
<Tailwind> classes inlined — once the styles are on the wire, rendering is guaranteed.PreviewProps to a long name and URL to stress the layout — the worst-case render proves the rest.The Resend SDK auto-derives the text/plain body from the react node you send. Given that, what’s the correct working habit for the plain-text version?
text string for every send so you control exactly what plain-text readers see.render(<T/>, { plainText: true }) on the send path to guarantee the text part is generated.welcome.tsx — reword the copy, fix the link text, adjust an alt. Hand-maintaining a parallel string drifts from the HTML within a release or two. And the plainText flag on render is deprecated in favor of toPlainText(html); on the send path you pass the node and get both bodies for free.The plain-text tab shows the decorative sparkle image’s filename leaking in as a stray line above the greeting. What’s the right fix, and what’s the trap?
alt to an explicit empty string — that drops it from the text. The trap is doing the same to an informational image, which silences real content for screen-reader users.width/height so the generator emits less text for it.alt="" marks an image as decorative, so the generator skips it. There’s no separate text file to edit — it’s re-derived from the JSX every render. The trap is using alt="" to “clean up” an informational image: that empties the alt to silence the text and blinds screen-reader users to real content. width/height are layout only and have no bearing on the text body.You ship a CTA whose text only clears 4.5:1 contrast after a client applies your @media (prefers-color-scheme: dark) styles. In its light form it sits at 3:1. Is the template accessible enough to ship?
<style> blocks), so dark mode is a courtesy layer, never the contrast strategy.color-scheme meta tags are present so the dark styles are guaranteed to apply.<style> blocks outright, so the dark rules may never arrive. The light, inline-styled template has to pass on its own. Dark mode sits on top of a template that already passes; it never makes one pass.You add Tailwind dark: utilities to your CTA but put nothing else in <Head>. A user opens it in Apple Mail with the OS set to dark. What happens?
color-scheme and supported-color-schemes meta tags. The plumbing is the opt-in.dark: styles automatically, because it always honors prefers-color-scheme.dark: styles are redundant.<meta name="color-scheme"> and <meta name="supported-color-schemes">, Apple Mail won’t apply your dark styles even with the user in dark mode — your dark: (or @media) rules are simply ignored. Apple Mail is a “no transformation” client, so it doesn’t blanket-invert; the styling rides on top of the declared plumbing.Quiz complete
Score by topic