Email 核心服務(Resend / 交易與通知郵件)

Resend 在 Next.js 商城中常用於交易郵件與通知郵件。以下整理 5 種實際情境(含程式碼片段),用來提升客戶互動與自動化,同時降低客服與營運成本。

Resend 5 種常見情境(含程式碼片段)

以下範例以服務商的口吻整理,重點在「事件觸發點」與「內容結構」。實作上通常會在 API Route 或 Server Action 內發信,避免前端暴露金鑰。

1. 訂單確認信

訂單完成後自動發送確認郵件,包含訂單明細與追蹤連結,讓客戶在付款後立即獲得回饋與信任。

情境

  • 電商結帳完成 → 立即寄出訂單確認
  • 可附上:訂單編號、商品清單、配送資訊、客服聯絡方式

範例(API Route)

程式碼片段:Resend 發送訂單確認信(簡版)
await resend.emails.send({
  from: '商城 <orders@yourstore.com>',
  to: [user.email],
  subject: '訂單確認',
  react: OrderConfirmation({ orderId: '123', items: order.items })
});

React Email 組件範例(OrderConfirmation.tsx)

建議用 React Email 組件設計訂單確認信:包含訂單摘要、感謝語、以及「追蹤訂單」的行動按鈕,提升開信率與品牌信任。以下是一個完整可用的結構範例(含 HTML 結構與樣式宣告),可放在 Next.js 專案內的 components/emails/OrderConfirmation.tsx

程式碼片段:OrderConfirmation.tsx(React Email 模板)
import * as React from "react";
import {
  Body,
  Button,
  Container,
  Head,
  Html,
  Img,
  Preview,
  Section,
  Text,
  Hr,
} from "@react-email/components";

interface Props {
  orderId: string;
  customerName: string;
  items: Array<{ name: string; qty: number; price: number }>;
  total: number;
  trackingUrl?: string;
}

export const OrderConfirmation = ({
  orderId,
  customerName,
  items,
  total,
  trackingUrl,
}: Props) => (
  <Html>
    <Head />
    <Preview>訂單 {orderId} 確認 - 感謝您的購買!</Preview>
    <Body style={main}>
      <Container style={container}>
        <Section style={logoSection}>
          <Img width={120} src="https://yourstore.com/logo.png" alt="商城Logo" />
        </Section>

        <Text style={heading}>Hi {customerName},您的訂單已確認!</Text>
        <Text style={text}>訂單編號:#{orderId}</Text>

        <Section style={table}>
          <table role="presentation" style={tableStyle}>
            <tr><th>商品</th><th>數量</th><th>單價</th></tr>
            {items.map((item, i) => (
              <tr key={i}>
                <td>{item.name}</td>
                <td>{item.qty}</td>
                <td>NT${item.price}</td>
              </tr>
            ))}
          </table>
        </Section>

        <Text style={text}><strong>總計:NT${total}</strong></Text>

        {trackingUrl && (
          <Section>
            <Button href={trackingUrl} style={button}>追蹤訂單</Button>
          </Section>
        )}

        <Hr />
        <Text style={footer}>感謝光臨,有問題請聯絡客服:support@yourstore.com</Text>
      </Container>
    </Body>
  </Html>
);

const main = { backgroundColor: "#f6f9fc", fontFamily: "sans-serif" };
const container = { margin: "0 auto", padding: "20px", maxWidth: "600px" };
const logoSection = { paddingBottom: "10px" };
const heading = { fontSize: "22px", fontWeight: "700", margin: "10px 0" };
const text = { fontSize: "14px", lineHeight: "20px" };
const footer = { fontSize: "12px", color: "#666" };
const button = { backgroundColor: "#111", color: "#fff", padding: "12px 16px", borderRadius: "8px", textDecoration: "none" };
const table = { marginTop: "10px", marginBottom: "10px" };
const tableStyle = { width: "100%", borderCollapse: "collapse" };

此模板可依品牌視覺再調整(Logo、字體、按鈕色),並可加上積分提示(例如:本次獲得 50 積分)或售後 CTA(例如:加入會員專區查看訂單)。

發送信件 API 範例(Route Handler)

以下示意一個 Next.js Route Handler:接收訂單資料後呼叫 Resend 發送 React Email 模板。訂單完成後(例如 Stripe webhook 或資料庫訂單狀態更新)以 POST 呼叫此 API 即可。

程式碼片段:send-order-confirmation Route Handler
import { Resend } from "resend";
import { OrderConfirmation } from "@/components/emails/OrderConfirmation";
import { NextRequest, NextResponse } from "next/server";

const resend = new Resend(process.env.RESEND_API_KEY!);

export async function POST(req: NextRequest) {
  const { userEmail, orderData } = await req.json();

  try {
    const data = await resend.emails.send({
      from: "訂單通知 <orders@yourstore.com>",
      to: [userEmail],
      subject: `訂單 ${orderData.id} 確認`,
      react: OrderConfirmation(orderData),
    });

    return NextResponse.json({ success: true, data });
  } catch (error) {
    return NextResponse.json({ error }, { status: 500 });
  }
}

最佳實務(純文字整理)

  • 觸發點:建議由 webhook / 後端事件觸發(付款成功、出貨、退款),避免依賴前端請求。
  • 可觀測性:每次發信要記錄 orderId、收件人、結果、錯誤訊息,方便排查。
  • 內容一致:交易信務必附上訂單查詢入口與客服聯絡方式。

2. 購物車遺棄提醒

偵測遺棄車後 24 小時寄出提醒郵件,附上商品摘要與優惠碼,回收流失訂單。

情境

  • 使用者加入購物車但未結帳 → 延遲 24 小時(或 1–3 小時)提醒
  • 可搭配排程:Cron job、Queue、或非同步 Trigger 工具,避免阻塞主交易流程

範例

程式碼片段:遺棄車提醒信
await resend.emails.send({
  to: [user.email],
  subject: '別忘了你的購物車!',
  react: CartReminder({ cartItems: abandonedCart })
});

3. 密碼重置

用戶忘記密碼時發送重置連結(或魔法連結),減少 SMS 成本並提升登入便利。

情境

  • 使用者忘記密碼 → 寄出一次性 token 的重置連結
  • 連結需設定有效期限並確保只能使用一次

範例

程式碼片段:寄出密碼重置連結
const resetLink = `${baseUrl}/reset?token=${token}`;
await resend.emails.send({
  to: [email],
  subject: '重置密碼',
  html: `<a href="${resetLink}">點擊重置</a>`
});

4. 歡迎 / 註冊通知

新會員註冊後寄出歡迎信,介紹會員權益、積分/新手優惠、個人化推薦入口,提升首購率。

情境

  • 註冊完成 → 寄出歡迎信
  • 可依註冊來源(廣告/SEO/合作)切不同內容與 CTA

範例

程式碼片段:歡迎信(註冊後觸發)
await resend.emails.send({
  to: [email],
  subject: '歡迎加入!',
  react: WelcomeEmail({ name: user.name, points: 100 })
});

5. 文件 / 頁面瀏覽通知

當文件或重要頁面被瀏覽時通知擁有者,適用於 SaaS、部落格後台或內部管理系統。

情境

  • 某頁面被瀏覽 / 某內容被查看 → 通知擁有者或管理員
  • 多數情況建議非同步發送,避免影響用戶端體驗

範例

程式碼片段:瀏覽通知信
await resend.emails.send({
  to: [owner.email],
  subject: '文件有新瀏覽!',
  react: NotificationEmail({ name: owner.name })
});

為什麼 Email 模組是核心(互動效益)

串接 Email 模組能把「被動接收」的客服互動,轉為「主動觸發」的個人化體驗:讓客戶在關鍵時刻收到明確回饋與引導,提升信任、留存與轉換。

三種常見價值

  • 個人化互動:基於購買/瀏覽歷史推送推薦、生日優惠、專屬預覽
  • 自動化觸發:遺棄車、訂單確認、物流更新、售後關懷
  • 忠誠與社群:積分通知、推薦獎勵、回饋問卷,形成口碑循環
互動類型 客戶體驗益處 常見結果
個人化推薦 感覺被了解,提升信任 提升開信率與點擊率
自動提醒 即時便利,減少流失 遺棄車回收、降低客服詢問
感謝 / 售後 情感連結,忠誠度更高 提升回購與評價
促銷活動 興奮參與,社群擴散 短期轉換提升

Resend + Vercel 常見問題與解決步驟

Resend 在 Vercel 部署後常見「本地正常、生產失敗」的原因,多半集中在環境變數、執行時間、路由設定與寄件網域驗證。以下整理 5 類問題與快速處理方式。

1) 環境變數未載入

  • 現象:本地可寄,部署後回傳 500;Log 顯示找不到 RESEND_API_KEY 或值為空。
  • 處理:在部署平台的環境變數設定加入 RESEND_API_KEY,並確保套用到 Production/Preview/Development(依你的工作流)。
  • 驗證:查看 Function Logs,確認 process.env.RESEND_API_KEY 存在。

2) 生產超時(504 / Timeout)

  • 現象:偶發或固定超時,尤其在尖峰或 email template 渲染較重時。
  • 處理:把發信改成非同步(Queue / 排程 / 觸發工具),或增加函式執行時間上限(依部署平台能力)。
  • 替代:若 SDK 造成延遲,也可改成直接呼叫 Resend HTTP API(server-side)。

3) API 路由錯誤(500 / 404)

  • 現象:Route Handler 沒有 export POST、路徑放錯、或 email component import 導致 runtime error。
  • 處理:確認 export async function POST(req) {} 存在且路徑正確;Email 組件避免 client-side 匯入。
  • 驗證:查看部署平台 function log 內是否有 TypeError 或 module not found。

4) 寄件網域 / DNS 未驗證(容易進垃圾桶或被拒收)

  • 現象:寄出成功但收件夾收不到、或被判定為垃圾信。
  • 處理:完成寄件網域驗證(SPF/DKIM 等),並固定 from 域名一致。
  • 驗證:用測試收件信箱比對 delivered/spam 狀態,並觀察 bounce/complaint。

5) 依賴 / 建置失敗

  • 現象:部署時 build fail、或 runtime 缺少 resend/@react-email/components。
  • 處理:確認依賴已安裝並提交 lockfile;部署環境 Node 版本建議與本地一致。

快速診斷清單

  • Logs:先看 Functions logs 的第一個錯誤堆疊(通常最關鍵)。
  • Keys:確認 Production 環境變數都有設定,且 redeploy 後生效。
  • Domains:確認寄件域名驗證完成,並用固定 from。
  • Timeout:交易流程不要同步等待寄信完成,改非同步。
  • Fallback:必要時先改成最小 HTML 寄送,排除 React Email 渲染造成的問題。

工具比較(Email 服務)

不同工具定位不同:交易/通知郵件重送達率與可程式化;行銷/Newsletter 重模板、受眾管理與自動化流程。

工具 優勢 Next.js 整合 價格(起) 適合情境
Resend React Email 支援、開發友好 npm + API(Server Actions / Routes) $0/月(入門) 交易/通知郵件
SendGrid 高送達、分析完善 API / SMTP $0/月(入門) 高量交易信
Mailchimp 行銷自動化、模板豐富 API / 自動化串接 $0/月(入門) 行銷/Newsletter
Brevo CRM + 多渠道(Email/SMS) API / 外掛 $0/月(入門) 電商全功能整合
Benchmark 在地支援、群發工具 外掛 / API 試用方案 EDM 群發

開始專案

如果你需要把交易郵件、通知郵件、以及行銷自動化整理成可維護的模組(含模板、追蹤、與排程),我們可以把 Email 規劃納入網站/商城的里程碑,讓營運從一開始就有「可追蹤、可自動化」的溝通機制。