{"id":24837,"plugin_id":"plugin_connector_690a90ec05c881918afb6a55dc9bbaa1","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T23:18:43.733Z","digest":"936fe46d17be7e45cc4b31e1b7ba0b5b60873b14ce02622188a60cd6f260ef35","against":5242,"payload":{"name":"email","description":"Email sending integration guidance — Resend (native Vercel Marketplace) with React Email templates. Covers API setup, transactional emails, domain verification, and template patterns. Use when sending emails from a Vercel-deployed application.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":159}],"skill_md_contents":"---\nname: email\ndescription: Email sending integration guidance — Resend (native Vercel Marketplace) with React Email templates. Covers API setup, transactional emails, domain verification, and template patterns. Use when sending emails from a Vercel-deployed application.\nmetadata:\n  priority: 4\n  docs:\n    - \"https://resend.com/docs\"\n    - \"https://react.email/docs/introduction\"\n  sitemap: \"https://resend.com/sitemap.xml\"\n  pathPatterns:\n    - 'emails/**'\n    - 'src/emails/**'\n    - 'components/emails/**'\n    - 'src/components/emails/**'\n    - 'app/api/send/**'\n    - 'src/app/api/send/**'\n    - 'app/api/email/**'\n    - 'src/app/api/email/**'\n    - 'app/api/emails/**'\n    - 'src/app/api/emails/**'\n    - 'lib/resend.*'\n    - 'src/lib/resend.*'\n    - 'lib/email.*'\n    - 'src/lib/email.*'\n    - 'lib/email*'\n    - 'src/lib/email*'\n    - '**/email-template*'\n  bashPatterns:\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bresend\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bresend\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bresend\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*\\bresend\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@react-email/'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@react-email/'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@react-email/'\n    - '\\byarn\\s+add\\s+[^\\n]*@react-email/'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*react-email\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*react-email\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*react-email\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*react-email\\b'\n---\n\n# Email Integration (Resend + React Email)\n\nYou are an expert in sending emails from Vercel-deployed applications — covering Resend (native Vercel Marketplace integration), React Email templates, domain verification, and transactional email patterns.\n\n## Vercel Marketplace Setup (Recommended)\n\nResend is a native Vercel Marketplace integration with auto-provisioned API keys and unified billing.\n\n### Install via Marketplace\n\n```bash\n# Install Resend from Vercel Marketplace (auto-provisions env vars)\nvercel integration add resend\n```\n\nAuto-provisioned environment variables:\n- `RESEND_API_KEY` — server-side API key for sending emails\n\n### SDK Setup\n\n```bash\n# Install the Resend SDK\nnpm install resend\n\n# Install React Email for building templates\nnpm install react-email @react-email/components\n```\n\n### Initialize the Client\n\nCurrent Resend SDK version: **6.9.x** (actively maintained, weekly downloads ~1.6M).\n\n```ts\n// lib/resend.ts\nimport { Resend } from \"resend\";\n\nexport const resend = new Resend(process.env.RESEND_API_KEY);\n```\n\n## Sending Emails\n\n### Basic API Route\n\n```ts\n// app/api/send/route.ts\nimport { NextResponse } from \"next/server\";\nimport { resend } from \"@/lib/resend\";\n\nexport async function POST(req: Request) {\n  const { to, subject, html } = await req.json();\n\n  const { data, error } = await resend.emails.send({\n    from: \"Your App <hello@yourdomain.com>\",\n    to,\n    subject,\n    html,\n  });\n\n  if (error) {\n    return NextResponse.json({ error }, { status: 400 });\n  }\n\n  return NextResponse.json({ id: data?.id });\n}\n```\n\n### Send with React Email Template\n\n```ts\n// app/api/send/route.ts\nimport { NextResponse } from \"next/server\";\nimport { resend } from \"@/lib/resend\";\nimport WelcomeEmail from \"@/emails/welcome\";\n\nexport async function POST(req: Request) {\n  const { name, email } = await req.json();\n\n  const { data, error } = await resend.emails.send({\n    from: \"Your App <hello@yourdomain.com>\",\n    to: email,\n    subject: \"Welcome!\",\n    react: WelcomeEmail({ name }),\n  });\n\n  if (error) {\n    return NextResponse.json({ error }, { status: 400 });\n  }\n\n  return NextResponse.json({ id: data?.id });\n}\n```\n\n## React Email Templates\n\n### Template Structure\n\nOrganize templates in an `emails/` directory at the project root:\n\n```\nemails/\n  welcome.tsx\n  invoice.tsx\n  reset-password.tsx\n```\n\n### Example Template\n\n```tsx\n// emails/welcome.tsx\nimport {\n  Body,\n  Container,\n  Head,\n  Heading,\n  Html,\n  Link,\n  Preview,\n  Text,\n} from \"@react-email/components\";\n\ninterface WelcomeEmailProps {\n  name: string;\n}\n\nexport default function WelcomeEmail({ name }: WelcomeEmailProps) {\n  return (\n    <Html>\n      <Head />\n      <Preview>Welcome to our platform</Preview>\n      <Body style={{ fontFamily: \"sans-serif\", backgroundColor: \"#f6f9fc\" }}>\n        <Container style={{ padding: \"40px 20px\", maxWidth: \"560px\" }}>\n          <Heading>Welcome, {name}!</Heading>\n          <Text>\n            Thanks for signing up. Get started by visiting your{\" \"}\n            <Link href=\"https://yourdomain.com/dashboard\">dashboard</Link>.\n          </Text>\n        </Container>\n      </Body>\n    </Html>\n  );\n}\n```\n\n### Preview Templates Locally\n\n```bash\n# Start the React Email dev server to preview templates\nnpx react-email dev\n```\n\nThis opens a browser preview at `http://localhost:3000` where you can view and iterate on email templates with hot reload.\n\n### Upload Templates to Resend (React Email 5.0)\n\n```bash\n# Upload templates directly from the CLI\nnpx react-email@latest resend setup\n```\n\nPaste your API key when prompted — templates are uploaded and available in the Resend dashboard.\n\n### Dark Mode Support (React Email 5.x)\n\nReact Email 5.x (latest 5.2.9, `@react-email/components` 1.0.8) supports dark mode with a theming system tested across popular email clients. Now also supports **React 19.2** and **Next.js 16**. Use the `Tailwind` component with Tailwind CSS v4 for email styling:\n\n```tsx\nimport { Tailwind } from \"@react-email/components\";\n\nexport default function MyEmail() {\n  return (\n    <Tailwind>\n      <div className=\"bg-white dark:bg-gray-900 text-black dark:text-white\">\n        <h1>Hello</h1>\n      </div>\n    </Tailwind>\n  );\n}\n```\n\n**Upgrade note (v4 → v5)**: Replace all `renderAsync` with `render`. The Tailwind component now only supports Tailwind CSS v4.\n\n## Domain Verification\n\nTo send from a custom domain (not `onboarding@resend.dev`), verify your domain in Resend:\n\n1. Go to [Resend Domains](https://resend.com/domains)\n2. Add your domain\n3. Add the DNS records (MX, SPF, DKIM) to your domain provider\n4. Wait for verification (usually under 5 minutes)\n\nUntil your domain is verified, use `onboarding@resend.dev` as the `from` address for testing.\n\n## Common Patterns\n\n### Batch Sending\n\n```ts\nconst { data, error } = await resend.batch.send([\n  {\n    from: \"hello@yourdomain.com\",\n    to: \"user1@example.com\",\n    subject: \"Update\",\n    html: \"<p>Content for user 1</p>\",\n  },\n  {\n    from: \"hello@yourdomain.com\",\n    to: \"user2@example.com\",\n    subject: \"Update\",\n    html: \"<p>Content for user 2</p>\",\n  },\n]);\n```\n\n### Server Action\n\n```ts\n\"use server\";\nimport { resend } from \"@/lib/resend\";\nimport WelcomeEmail from \"@/emails/welcome\";\n\nexport async function sendWelcomeEmail(name: string, email: string) {\n  const { error } = await resend.emails.send({\n    from: \"Your App <hello@yourdomain.com>\",\n    to: email,\n    subject: \"Welcome!\",\n    react: WelcomeEmail({ name }),\n  });\n\n  if (error) throw new Error(\"Failed to send email\");\n}\n```\n\n### Broadcast API (February 2026)\n\nSend emails to audiences (mailing lists) managed in Resend:\n\n```ts\n// Send a broadcast to an audience\nconst { data, error } = await resend.broadcasts.send({\n  audienceId: \"aud_1234\",\n  from: \"updates@yourdomain.com\",\n  subject: \"Monthly Newsletter\",\n  react: NewsletterEmail({ month: \"March\" }),\n});\n\n// Create and manage broadcasts programmatically\nconst broadcast = await resend.broadcasts.create({\n  audienceId: \"aud_1234\",\n  from: \"updates@yourdomain.com\",\n  subject: \"Product Update\",\n  react: ProductUpdateEmail(),\n});\n\n// Schedule for later\nawait resend.broadcasts.send({\n  broadcastId: broadcast.data?.id,\n  scheduledAt: \"2026-03-15T09:00:00Z\",\n});\n```\n\n### Idempotency Keys\n\nPrevent duplicate sends on retries by passing an `Idempotency-Key` header:\n\n```ts\nconst { data, error } = await resend.emails.send(\n  {\n    from: \"hello@yourdomain.com\",\n    to: \"user@example.com\",\n    subject: \"Order Confirmation\",\n    react: OrderConfirmation({ orderId: \"ord_123\" }),\n  },\n  {\n    headers: {\n      \"Idempotency-Key\": `order-confirmation-ord_123`,\n    },\n  }\n);\n```\n\nResend deduplicates requests with the same idempotency key within a 24-hour window. Use deterministic keys derived from your business logic (e.g., `order-confirmation-${orderId}`).\n\n### Webhook Management API\n\nCreate and manage webhooks programmatically instead of through the dashboard:\n\n```ts\n// Create a webhook endpoint\nconst { data } = await resend.webhooks.create({\n  url: \"https://yourdomain.com/api/webhook/resend\",\n  events: [\"email.delivered\", \"email.bounced\", \"email.complained\", \"email.suppressed\"],\n});\n\n// List all webhooks\nconst webhooks = await resend.webhooks.list();\n\n// Delete a webhook\nawait resend.webhooks.remove(webhookId);\n```\n\n### Email Status: \"suppressed\"\n\nResend now tracks a `\"suppressed\"` delivery status for recipients on suppression lists (previous hard bounces or spam complaints). Check for this in webhook events alongside delivered/bounced/complained.\n\n### Webhook for Delivery Events\n\n```ts\n// app/api/webhook/resend/route.ts\nimport { NextResponse } from \"next/server\";\n\nexport async function POST(req: Request) {\n  const event = await req.json();\n\n  switch (event.type) {\n    case \"email.delivered\":\n      // Track successful delivery\n      break;\n    case \"email.bounced\":\n      // Handle bounce — remove from mailing list\n      break;\n    case \"email.complained\":\n      // Handle spam complaint — unsubscribe user\n      break;\n  }\n\n  return NextResponse.json({ received: true });\n}\n```\n\n## Environment Variables\n\n| Variable | Scope | Description |\n|----------|-------|-------------|\n| `RESEND_API_KEY` | Server | Resend API key (starts with `re_`) |\n\n## Cross-References\n\n- **Marketplace install and env var provisioning** → `⤳ skill: marketplace`\n- **API route patterns** → `⤳ skill: routing-middleware`\n- **Environment variable management** → `⤳ skill: env-vars`\n- **Serverless function config** → `⤳ skill: vercel-functions`\n\n## Official Documentation\n\n- [Resend + Vercel Marketplace](https://vercel.com/marketplace/resend)\n- [Resend Documentation](https://resend.com/docs)\n- [Resend Next.js Quickstart](https://resend.com/docs/send-with-nextjs)\n- [React Email Documentation](https://react.email/docs/introduction)\n- [React Email Components](https://react.email/docs/components/html)\n"},"changes":[{"path":"/included_files","type":"changed","before":[],"after":[{"relative_path":"agents/openai.yaml","size_in_bytes":159}]}],"summary":"Fields changed: 1. /included_files.","summary_kind":"deterministic","summary_metadata":{}}