如何在Next.js中实现无需新开窗口的自定义邮件发送表单?
实现Next.js邮件表单(无需打开邮件客户端)
需求说明
我想在个人作品集网站中添加一个邮件样式的联系模块,不想只用邮件链接,要做完整表单让用户无需新开窗口就能发邮件。用户可输入姓名、邮箱、主题、内容,点击发送按钮完成操作。设计参考The Craftsmen网站的邮件表单,目前用Next.js开发,已有基础代码框架:
<section id='contact'> <div > <form action="" > <div> <div > <input type="text" placeholder="Name"/> <input type="email" placeholder='E-mail'/> <input type="text" placeholder='Subject'/> <input type="text" placeholder='Message'/> </div> <div > <button type="submit">Send</button> </div> </div> </form> </div> </section>
问题: 请问是否有办法将这些输入值转化为邮件自动发送给我,且无需打开用户浏览器中的邮件客户端?
实现方案
要实现无客户端发送邮件,核心是通过后端服务处理邮件发送逻辑,前端只负责收集表单数据并提交到后端。下面是几种适合Next.js的实用方案:
1. 使用Next.js API Routes(推荐)
Next.js自带的API Routes可以直接在项目内创建后端接口,不用额外搭建服务器,步骤简单:
第一步:完善前端表单
给表单添加提交事件处理,给输入框加name属性方便获取数据,同时把内容输入改成textarea更适合长文本:
'use client'; // App Router需要添加,Pages Router无需 export default function ContactSection() { const handleSubmit = async (e) => { e.preventDefault(); const formData = new FormData(e.target); const data = Object.fromEntries(formData); try { const res = await fetch('/api/send-email', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); if (res.ok) { alert('邮件发送成功!'); e.target.reset(); } else { alert('发送失败,请重试'); } } catch (err) { console.error(err); alert('发送出错,请稍后再试'); } }; return ( <section id='contact'> <div> <form onSubmit={handleSubmit}> <div> <div> <input type="text" name="name" placeholder="Name" required /> <input type="email" name="email" placeholder='E-mail' required /> <input type="text" name="subject" placeholder='Subject' required /> <textarea name="message" placeholder='Message' rows="5" required /> </div> <div> <button type="submit">Send</button> </div> </div> </form> </div> </section> ); }
第二步:创建API Route处理邮件发送
在项目里创建邮件处理的API接口:
- Pages Router:在
pages/api目录下新建send-email.js - App Router:在
app/api/send-email目录下新建route.js
先安装邮件发送库nodemailer:
npm install nodemailer # 或 yarn add nodemailer
然后编写API代码(以Pages Router为例,App Router语法逻辑一致):
import nodemailer from 'nodemailer'; export default async function handler(req, res) { // 仅允许POST请求 if (req.method !== 'POST') { return res.status(405).json({ message: '仅支持POST请求' }); } const { name, email, subject, message } = req.body; // 配置邮件发送器,此处以Gmail为例,也可使用Outlook、QQ邮箱等 const transporter = nodemailer.createTransport({ service: 'Gmail', auth: { user: process.env.YOUR_EMAIL, // 你的邮箱地址,存于环境变量 pass: process.env.YOUR_EMAIL_PASSWORD, // 邮箱授权码(非登录密码) }, }); // 构建邮件内容 const mailOptions = { from: email, // 用户填写的邮箱 to: process.env.TARGET_EMAIL, // 接收邮件的你的邮箱 subject: `作品集网站消息:${subject}`, text: `发件人:${name}\n联系邮箱:${email}\n\n消息内容:\n${message}`, // 也可使用HTML格式美化邮件: // html: `<h3>来自作品集的消息</h3><p><strong>发件人:</strong>${name}</p><p><strong>邮箱:</strong>${email}</p><p><strong>内容:</strong>${message}</p>` }; try { await transporter.sendMail(mailOptions); res.status(200).json({ message: '邮件发送成功' }); } catch (error) { console.error(error); res.status(500).json({ message: '邮件发送失败,请稍后再试' }); } }
2. 使用第三方邮件服务(更稳定)
如果不想自己配置邮箱服务器,推荐用专业邮件服务(如SendGrid、Mailgun),配置简单且送达率更高。以SendGrid为例:
步骤:
- 注册SendGrid账号,获取API Key并验证发件邮箱/域名
- 安装依赖:
npm install @sendgrid/mail
- 修改API Route代码:
import sgMail from '@sendgrid/mail'; // 从环境变量读取API Key sgMail.setApiKey(process.env.SENDGRID_API_KEY); export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).json({ message: '仅支持POST请求' }); } const { name, email, subject, message } = req.body; const msg = { to: process.env.TARGET_EMAIL, // 你的接收邮箱 from: process.env.SENDGRID_VERIFIED_EMAIL, // 你在SendGrid验证过的发件邮箱 subject: `作品集网站消息:${subject}`, text: `发件人:${name}\n联系邮箱:${email}\n\n消息内容:\n${message}`, }; try { await sgMail.send(msg); res.status(200).json({ message: '发送成功' }); } catch (error) { res.status(500).json({ message: '发送失败' }); } }
关键注意事项
- 敏感信息存环境变量:把邮箱地址、授权码、API Key存在项目根目录的
.env.local文件里,示例:YOUR_EMAIL=your@email.com YOUR_EMAIL_PASSWORD=your-app-password TARGET_EMAIL=your-receive@email.com SENDGRID_API_KEY=your-sendgrid-key - 邮箱授权设置:比如Gmail需要开启两步验证后生成「应用专用密码」;QQ邮箱要开启POP3/SMTP服务
- 表单验证:前端加
required属性做基础验证,后端也要校验数据格式,防止恶意提交 - 样式优化:根据参考的邮件样式,给表单添加CSS,模拟邮件的边框、排版等视觉效果
内容的提问来源于stack exchange,提问作者JacoCoder
相关产品推荐
相关产品推荐

