mirror of
https://github.com/resend/react-email.git
synced 2026-09-14 14:18:02 +08:00
feat(skill): add email accessibility guidance to skill (#3551)
Co-authored-by: Hermes <hermes@resend.com>
This commit is contained in:
committed by
GitHub
parent
62630604e9
commit
6107e01f98
@@ -19,7 +19,7 @@ metadata:
|
|||||||
|
|
||||||
# React Email
|
# React Email
|
||||||
|
|
||||||
Build and send HTML emails using React components - a modern, component-based approach to email development that works across all major email clients.
|
Build and send HTML emails using React components. A modern, component-based approach to email development that works across all major email clients.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -355,12 +355,36 @@ See [references/PATTERNS.md](references/PATTERNS.md) for complete examples inclu
|
|||||||
|
|
||||||
1. **Test across email clients** - Gmail, Outlook, Apple Mail, Yahoo Mail
|
1. **Test across email clients** - Gmail, Outlook, Apple Mail, Yahoo Mail
|
||||||
2. **Keep it responsive** - Max-width around 600px, test on mobile
|
2. **Keep it responsive** - Max-width around 600px, test on mobile
|
||||||
3. **Use absolute image URLs** - Host on reliable CDN, always include `alt` text
|
3. **Use absolute image URLs** - Host on reliable CDN
|
||||||
4. **Provide plain text version** - Required for accessibility
|
4. **Write meaningful alt text** - Describe purpose and details for content images; use `alt=""` for decorative images (spacers, dividers, background flourishes). React Email's `<Img>` defaults to `alt=""`.
|
||||||
5. **Keep file size under 102KB** - Gmail clips larger emails
|
5. **Provide plain text version** - Required for accessibility
|
||||||
6. **Add proper TypeScript types** - Define interfaces for all email props
|
6. **Keep file size under 102KB** - Gmail clips larger emails
|
||||||
7. **Include preview props** - Add `.PreviewProps` for development testing
|
7. **Add proper TypeScript types** - Define interfaces for all email props
|
||||||
8. **Use verified domains** - For production `from` addresses
|
8. **Include preview props** - Add `.PreviewProps` for development testing
|
||||||
|
9. **Use verified domains** - For production `from` addresses
|
||||||
|
|
||||||
|
### Accessibility
|
||||||
|
|
||||||
|
React Email handles the structural defaults; the rest is content.
|
||||||
|
|
||||||
|
**What React Email gives you for free:**
|
||||||
|
- `<Html>` sets `lang` and `dir` (defaults: `lang="en" dir="ltr"` — override per locale)
|
||||||
|
- `<Img>` defaults to `alt=""` so decorative images are skipped by screen readers
|
||||||
|
- `<Markdown>` renders layout tables with `role="presentation"`
|
||||||
|
- `<Preview>` also emits a `<title>` tag
|
||||||
|
|
||||||
|
Upgrade with `npm install react-email@latest` to get these defaults.
|
||||||
|
|
||||||
|
**What you still have to do (content choices):**
|
||||||
|
- Open with a single `<Heading as="h1">`, nest subheadings in order, never skip levels (very short SMS-style emails may skip the heading entirely)
|
||||||
|
- Set descriptive `alt` on meaningful images; pass an explicit `alt=""` on decorative images — never omit the attribute
|
||||||
|
- **Linked images are never decorative.** When an `<Img>` is inside a `<Link>` or `<Button>`, the `alt` must describe where the link goes — `alt=""` on a linked image leaves the link with no accessible name
|
||||||
|
- Write link text that describes the destination (`<Button>Read the report</Button>`, not `click here`)
|
||||||
|
- Hit 4.5:1 text contrast (WCAG AA); preview in dark mode
|
||||||
|
- For layout tables you build by hand (outside `<Markdown>`), add `role="presentation"`
|
||||||
|
- For non-English emails, pass the locale: `<Html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>` (see [I18N.md](references/I18N.md))
|
||||||
|
|
||||||
|
For the full rule set, severity ranking, and authoring checklist, see the [accessibility reference](https://github.com/resend/email-best-practices/blob/main/references/accessibility.md) in the `email-best-practices` skill.
|
||||||
|
|
||||||
## Additional Resources
|
## Additional Resources
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,8 @@ import { Section } from 'react-email';
|
|||||||
</Section>
|
</Section>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Layout components (`<Section>`, `<Row>`, `<Container>`, `<Markdown>` tables) render `<table role="presentation">` by default so screen readers don't announce them as data tables. If you drop in a raw `<table>` for layout, add `role="presentation"` yourself.
|
||||||
|
|
||||||
### Row & Column
|
### Row & Column
|
||||||
|
|
||||||
Row displays content areas horizontally, Column displays content areas vertically. A Column needs to be used in combination with a Row component.
|
Row displays content areas horizontally, Column displays content areas vertically. A Column needs to be used in combination with a Row component.
|
||||||
@@ -286,13 +288,15 @@ import { Img } from 'react-email';
|
|||||||
|
|
||||||
**Props:**
|
**Props:**
|
||||||
- `src` (required) - Image URL (must be absolute)
|
- `src` (required) - Image URL (must be absolute)
|
||||||
- `alt` (required) - Alt text for accessibility
|
- `alt` - Alt text for accessibility (defaults to `""`; set a descriptive value for meaningful images)
|
||||||
- `width` - Image width in pixels
|
- `width` - Image width in pixels
|
||||||
- `height` - Image height in pixels
|
- `height` - Image height in pixels
|
||||||
|
|
||||||
**Best practices:**
|
**Best practices:**
|
||||||
- Always use absolute URLs hosted on CDN
|
- Always use absolute URLs hosted on CDN
|
||||||
- Always include alt text
|
- **Meaningful images**: write descriptive `alt` text covering purpose and key details (e.g., `alt="Red bicycle leaning against a brick wall"`, not `alt="image"`)
|
||||||
|
- **Decorative images** (spacers, dividers, background flourishes): pass an explicit `alt=""` so screen readers skip them cleanly — never omit the attribute
|
||||||
|
- **Linked images are never decorative.** When `<Img>` sits inside a `<Link>` or `<Button>`, its `alt` must describe where the link goes (e.g., `alt="View order #123"`). An empty `alt=""` on a linked image leaves the link with no accessible name for screen readers
|
||||||
- Specify width and height to prevent layout shift
|
- Specify width and height to prevent layout shift
|
||||||
- Use `block` class to avoid spacing issues
|
- Use `block` class to avoid spacing issues
|
||||||
|
|
||||||
|
|||||||
@@ -153,14 +153,22 @@ Use consistent spacing that respects content hierarchy. Larger margins for headi
|
|||||||
- Never distort user-provided images
|
- Never distort user-provided images
|
||||||
- Never create SVG images
|
- Never create SVG images
|
||||||
- Always use absolute URLs
|
- Always use absolute URLs
|
||||||
- Include `alt` text for accessibility
|
- Set descriptive `alt` text on meaningful images; pass an explicit `alt=""` on decorative images so screen readers skip them — never omit the attribute
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
|
{/* Meaningful image — describe purpose and details */}
|
||||||
<Img
|
<Img
|
||||||
src="https://example.com/image.png"
|
src="https://example.com/hero.png"
|
||||||
alt="Description"
|
alt="A team of engineers reviewing code on a laptop"
|
||||||
className="w-full h-auto"
|
className="w-full h-auto"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Decorative image — always pass an empty alt string so screen readers skip it */}
|
||||||
|
<Img
|
||||||
|
src="https://example.com/divider.png"
|
||||||
|
alt=""
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Buttons
|
## Buttons
|
||||||
|
|||||||
Reference in New Issue
Block a user