
Email Best Practices
Ship Resend HTML emails that stay readable in screen readers, dark mode, translation tools, and AI agents.
Install
npx skills add https://github.com/resend/resend-skills --skill email-best-practicesWhat is this skill?
- Mechanical accessibility rules for production HTML email (lang, dir, tables, contrast)
- Requires BCP 47 lang and dir on both html and body direct children—documents the #1 client stripping failure
- Marks layout tables with role=presentation or role=none for screen readers
- Oriented to Resend sends and multi-locale templates—not one-off copy pastes
- Treats dark-mode, translation, and agent readability as first-class requirements
Adoption & trust: 2.6k installs on skills.sh; 129 GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Web Design Guidelinesvercel-labs/agent-skills
Lark Whiteboardlarksuite/cli
Ui Ux Pro Maxnextlevelbuilder/ui-ux-pro-max-skill
Sleek Design Mobile Appssleekdotdesign/agent-skills
Impeccablepbakaus/impeccable
Design Taste Frontendleonxlnx/taste-skill
Journey fit
Primary fit
Email templates are built as HTML markup alongside the product, so the canonical shelf is Build before messages go out. Accessibility and structure rules apply directly to email HTML layout, typography, and tables—the same surface area as frontend markup.
Common Questions / FAQ
Is Email Best Practices safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Email Best Practices
# Email Accessibility Emails must be readable by screen readers, dark-mode clients, translation tools, and AI agents — not just sighted readers on a default inbox. The rules below are mechanical. Apply them every time. ## Rules ### Set `lang` and `dir` on `<html>` and on `<body>`'s direct children (Serious) Both attributes are needed in **two places**: on `<html>` *and* on the direct children of `<body>`. Several email clients strip the attributes from `<html>`, which is why duplicating them on the body's children is the single most common accessibility failure in production email. ```html <html lang="en" dir="ltr"> <head> <title>Your weekly product updates</title> </head> <body> <div lang="en" dir="ltr"> <!-- email content --> </div> </body> </html> ``` - `lang`: a [BCP 47 language tag](https://developer.mozilla.org/en-US/docs/Glossary/BCP_47_language_tag) (`en`, `pt-BR`, `ja`, `ar`) - `dir`: `ltr`, `rtl`, or `auto` **Fallbacks when the correct values aren't available** (use only when you genuinely don't know): - `dir="auto"` — lets the user agent infer direction from content - `lang="und"` — marks the language as undetermined Both fallbacks are worse than the correct value but much better than nothing. For multi-locale templates, pass the locale through; do not hardcode `en`. ### Mark layout tables as presentational (Serious) Any `<table>` used for layout must have `role="presentation"` (or the equivalent `role="none"`). Otherwise screen readers announce "table, row 1 of N" for every layout row and the email becomes unusable. Prefer avoiding layout tables entirely; when you can't, mark them. ```html <table role="presentation" cellpadding="0" cellspacing="0" border="0"> <tr> <td>...</td> </tr> </table> ``` Leave a `<table>` without `role="presentation"` only when the data is genuinely tabular (line items, comparison rows). Tabular data should also use `<th scope="col">` for column headers. ### Use a single `<h1>` and nest headings in order (Mild) Most emails should have one `<h1>` that names the email, with subheadings nested in order:`<h1>` → `<h2>` → `<h3>`. Never skip levels. Never fake a heading with bold `<p>`. ```html <h1>Order confirmation</h1> <h2>Items</h2> <h2>Shipping</h2> <h3>Address</h3> <h3>Tracking</h3> ``` Headings are how assistive tech and AI clients navigate and summarize the email. **Exception:** very short messages (SMS-style notifications, single-sentence alerts) may not need a heading at all. If the email body is one or two sentences, skip the `<h1>` rather than wrap a heading around the only content. ### Every link must have discernible text (Serious) Every `<a>` must contain text content that a screen reader can announce. The most common failure is a linked image with no alt text. A **linked image is never decorative.** It's functional, so its `alt` must describe what clicking does, not just what the image looks like. ```html <!-- Wrong: linked image with no accessible name --> <a href="/order/123"> <img src="view-order.png" alt=""> </a> <!-- Right: alt describes the action --> <a href="/order/123"> <img src="view-order.png" alt="View order #123"> </a> <!-- Also right: visible text alongside the image --> <a href="/order/123"> <img src="icon.png" alt=""> View order #123 </a> ``` When the visible link text can't carry enough information, add visually hidden text inside the `<a>` (see [goodemailcode.com/email-accessibility/visually-hidden-text](https://www.goodemailcode.com/email-accessibility/visually-hidden-text)). `aria-label` and `title` on `<a>` have limited support in email clients. Prefer real text content or visually hidden text. ### Link text must describe the destination (Moderate) Even when a link has text, it must describe where the link goes. Never use "click here," "learn more," "read more," or bare URLs. Screen reader users often navigate by jumping between link texts with no surrounding context. ```html <!-