Next.js中SendGrid HTML邮件遍历News API数组问题求助
解决Next.js中SendGrid邮件无法生成URL列表的问题
你当前的核心问题有两个:一是直接在html字段写Handlebars语法无效,SendGrid默认不会自动解析这类模板语法,只会将其当作普通文本输出;二是你的Handlebars遍历写法本身有误——articles是数组,应该遍历数组本身而非articles.url,且遍历内部的取值逻辑也不对。
下面提供两种可行的解决方法:
方法1:手动生成HTML列表(无需额外依赖)
直接用JavaScript的数组方法生成符合要求的HTML字符串,这是最直接的方案:
import sendgrid from "@sendgrid/mail"; sendgrid.setApiKey(process.env.SENDGRID_API_KEY); export const sendLatestNewsEmail = async () => { const apiResponse = await fetch( `https://newsapi.org/v2/everything?from=2023-02-08&to=2023-02-09&sortBy=popularity`, { headers: { Authorization: `Bearer ${process.env.NEXT_PUBLIC_NEWS_KEY}`, }, } ); const json = await apiResponse.json(); const { articles } = json; // 生成URL列表的HTML字符串 const articlesListHtml = articles.length > 0 ? `<ul>${articles.map(article => `<li><a href="${article.url}">${article.url}</a></li>`).join('')}</ul>` : '<p>暂无新闻内容</p>'; const msg = { to: "myemail@gmail.com", // 接收邮件的地址 from: "myemail@gmail.com", // 发件地址(需在SendGrid验证) subject: `news app v2`, html: articlesListHtml, }; sendgrid .send(msg) .then(() => { console.log('Email sent') }) .catch((error) => { console.error(error) }); }; export default sendLatestNewsEmail;
- 用
map遍历每个新闻对象,取出url生成带<li>的字符串 - 用
join('')将数组转为连续的HTML文本,避免默认的逗号分隔 - 增加了数组长度判断,处理无新闻数据的边界情况
方法2:使用Handlebars编译模板(需额外依赖)
如果坚持要用Handlebars语法,需要先安装依赖并手动编译模板:
- 安装Handlebars:
npm install handlebars
- 修改代码:
import sendgrid from "@sendgrid/mail"; import handlebars from "handlebars"; sendgrid.setApiKey(process.env.SENDGRID_API_KEY); export const sendLatestNewsEmail = async () => { const apiResponse = await fetch( `https://newsapi.org/v2/everything?from=2023-02-08&to=2023-02-09&sortBy=popularity`, { headers: { Authorization: `Bearer ${process.env.NEXT_PUBLIC_NEWS_KEY}`, }, } ); const json = await apiResponse.json(); const { articles } = json; // 定义Handlebars模板,修正遍历逻辑 const template = handlebars.compile(` {{#if articles}} <ul> {{#each articles}} <li><a href="{{url}}">{{url}}</a></li> {{/each}} </ul> {{else}} <p>暂无新闻内容</p> {{/if}} `); // 传入数据生成最终HTML const html = template({ articles }); const msg = { to: "myemail@gmail.com", from: "myemail@gmail.com", subject: `news app v2`, html: html, }; sendgrid .send(msg) .then(() => { console.log('Email sent') }) .catch((error) => { console.error(error) }); }; export default sendLatestNewsEmail;
- 引入Handlebars库后,用
handlebars.compile编译模板字符串 - 修正遍历逻辑:直接遍历
articles数组,内部通过{{url}}取每个对象的链接 - 用
template({ articles })传入数据,生成可直接使用的HTML内容
内容的提问来源于stack exchange,提问作者BojPav
相关产品推荐
相关产品推荐

