电子邮件模板图像显示在预览中,但不显示在 Gmail 中
email-templates Images are shown in preview but not in Gmail
我正在使用 email-template 包来发送样式化的电子邮件。在电子邮件预览中似乎一切正常(预览选项在包本身中给出。如果设置为真,它会在选项卡中呈现已发送的电子邮件预览)。但是当我在我的 gmail 帐户中收到电子邮件时,图片是不可见的。我可以看出设置/代码中的路径/图像存在,因为在预览中一切都放置得恰到好处。
smtpTransport = nodemailer.createTransport(
smtpTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
jsonTransport: true,
auth: {
user: 'sender.example@gmail.com',
pass: '123123',
},
})
);
smtpTransport.use('compile', base64ToS3());
const templateWrapper = new Email({
transport: smtpTransport,
send: true,
preview: true,
views: {
options: {
extension: 'ejs',
},
root: path.join(__dirname, 'email/html/events'),
},
juice: true,
juiceSettings: {
tableElements: ['TABLE'],
},
juiceResources: {
preserveImportant: true,
webResources: {
relativeTo: path.join(__dirname, 'email/assets'),
images: true,
},
},
});
这是我的 HTML 模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Efys - Welcome</title>
<style>
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
body {
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 0.8rem;
line-height: 1.4;
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
.bg-brand-color-blue-dark {
background-color: #033e75;
}
.bg-brand-color-gold-light {
background-color: #f0ede6;
}
.bg-brand-color-gold-dark {
background-color: #d0a345;
}
.bg-white {
background-color: #ffffff;
}
.brand-color-gold-dark {
color: #d0a345;
}
.brand-color-gold-light {
color: #f0ede6;
}
.brand-color-blue-dark {
color: #033e75;
}
.text-color-white {
color: #ffffff;
}
.text-color-black {
color: #000000;
}
.display-block {
display: block;
}
.margin-top-0rem {
margin-top: 0;
}
.margin-top-1rem {
margin-top: 1rem;
}
.margin-top-2rem {
margin-top: 2rem;
}
.margin-bottom-2rem {
margin-bottom: 2rem;
}
.padding-full-1rem {
padding: 1rem;
}
.padding-full-2rem {
padding: 2rem;
}
.padding-top-2rem {
padding-top: 2rem;
}
.padding-bottom-5rem {
padding-top: 5rem;
}
.border-solid-black {
border: 1px solid #000000;
}
.border-radius-half {
border-radius: 0.5rem;
}
.border-radius-1rem {
border-radius: 1rem;
}
.whitespace {
white-space: normal;
}
.font-size-x1 {
font-size: 1rem;
}
.font-size-x2 {
font-size: 2rem;
}
a,
a:visited {
color: blue;
}
.text-decoration-none {
text-decoration: none;
}
ol {
padding-left: 15px;
}
p {
margin-top: 1rem;
margin-bottom: 0;
}
.strong {
font-weight: bold;
}
h3 {
margin-bottom: 0;
}
h3 + p {
margin-top: 0;
}
.inline-icon {
margin-right: 5px;
}
.flexbox {
display: flex;
}
.flex-row {
flex-direction: row;
}
.flex-nowrap {
flex-wrap: nowrap;
}
.flexbox .cell {
width: 50%;
}
.flexbox .cell:nth-child(2) {
text-align: right;
}
.maximum-width {
width: 100%;
max-width: 36.25rem;
margin: 0 auto;
}
.logo {
width: 100%;
max-width: 36.25rem;
margin: 0 auto;
}
.logo img {
border: 0 none;
outline: 0 none;
width: 100%;
height: auto;
}
@media only screen and (max-width: 480px) {
.footer > .flexbox .cell {
width: 100%;
text-align: center;
}
.footer > .flexbox .cell:nth-child(2) {
text-align: center;
margin-top: 1rem;
}
.footer > .flex-nowrap {
flex-wrap: wrap;
}
.inner-cell.flexbox {
display: block;
max-width: 100%;
margin: 0 auto;
}
}
</style>
</head>
<body>
<div
class="wrapper display-block bg-brand-color-blue-dark padding-full-1rem"
>
<!-- logo -->
<div class="logo display-block" style="margin: 0 auto;">
<img
class="display-block"
src="efy-registration-header.jpg"
alt="abc def"
style="border-top-left-radius: 1rem; border-top-right-radius: 1rem;"
/>
</div>
<!-- content -->
<div
class="content display-block maximum-width bg-white text-color-black padding-full-2rem"
style="border-bottom-left-radius: 1rem; border-bottom-right-radius: 1rem;"
>
<p class="strong">Dear <%= clientName %>,</p>
<p>
You have successfully registered for <%= efyTitle %> on <%= efyDay %> at <%= startTime %>
</p>
<p>Your Reference ID is: <%= referenceId %></p>
<% if (displayAddress) { %>
<p>Zoom link: <%= address %></p>
<% } else { %>
<p>
Zoom link: You should receive an email update with the link to the
live efy
</p>
<% } %>
<h3>Zoom Instructions</h3>
<p>To join a Zoom meeting on a computer or mobile device:</p>
<ol>
<li>
Download the Zoom app from their Download Center
<a href="https://zoom.us/download" target="_blank"
>https://zoom.us/download</a
>. Otherwise, you will be prompted to download and install Zoom when
you click a join link.
</li>
</ol>
</div>
<!-- footer -->
<div
class="footer maximum-width text-color-white"
style="margin: 1rem auto 5rem;"
>
<div
class="flexbox flex-row flex-nowrap"
style="justify-content: center; align-items: flex-end;"
>
<div class="cell">
<div class="flexbox flex-row flex-nowrap inner-cell">
<div class="col" style="margin-right: 0.5em;">
<img
src="logo_icon.png"
alt="abc def"
width="50"
height="auto"
/>
</div>
<div class="col">
Villa 1, Alwasl Rd. <br />
Alsafa 2 <br />
Dubai, United Arab Emirates
</div>
</div>
<p>
<span class="strong brand-color-gold-dark">T.</span>
<a
href="tel:+97143809298"
class="text-decoration-none strong"
style="color: #FFFFFF;"
>+971 (0)4 380 9296</a
>
</p>
<p class="margin-top-0rem">
<span class="strong brand-color-gold-dark">E.</span>
<a
href="mailto:info@example.com"
class="text-decoration-none strong"
style="color: #FFFFFF;"
>info@example.com</a
>
</p>
</div>
<div class="cell">
<p>
<span class="inline-icon"
><a href="#"
><img
src="icon-facebook.png"
width="40"
height="auto"/></a
></span>
<span class="inline-icon"
><a href="#"
><img
src="icon-twitter.png"
width="40"
height="auto"/></a
></span>
<span class="inline-icon"
><a href="#"
><img
src="icon-instagram.png"
width="40"
height="auto"/></a
></span>
<span class="inline-icon"
><a href="#"
><img
src="icon-linkedin.png"
width="40"
height="auto"/></a
></span>
</p>
<p class="brand-color-gold-dark strong">@example.com</p>
<p class="margin-top-0rem">
<span class="strong brand-color-gold-dark">W.</span>
<a
href="//example.com"
class="text-decoration-none strong"
style="color: #FFFFFF;"
>example.com</a
>
</p>
</div>
</div>
</div>
</div>
</body>
</html>
当您加载 HTML 页面并使用如下图片时
<img
src="icon-linkedin.png"
width="40"
height="auto"
/>
它实际上告诉浏览器,从加载 HTML 页面的同一目录加载图像。
问题来了。当您的电子邮件在 Gmail
中加载时,它也会告诉浏览器相同的信息,并且浏览器将无法找到该图像。
解法:
如果您是从后端发送的。然后上传任意publicurl中的图片。您可以在前端托管中上传图片并找到 link。然后直接使用link。您的图片需要 public 才能访问。
如果您没有任何其他选择或托管。在任何 public github/gitlab 存储库中上传图像并使用 link.
According to the docs for nodemailer-base64-to-s3
,需要在base64ToS3
方法中传入一些配置选项。它说 aws/params/Bucket
是必需的。
我相信以下内容应该会给您一个良好的开端:
smtpTransport.use('compile', base64ToS3({
aws: {
params: {
Bucket: "bucket_name_here"
}
}
}));
另一个例子见https://github.com/forwardemail/nodemailer-base64-to-s3/blob/master/example.js。
我正在使用 email-template 包来发送样式化的电子邮件。在电子邮件预览中似乎一切正常(预览选项在包本身中给出。如果设置为真,它会在选项卡中呈现已发送的电子邮件预览)。但是当我在我的 gmail 帐户中收到电子邮件时,图片是不可见的。我可以看出设置/代码中的路径/图像存在,因为在预览中一切都放置得恰到好处。
smtpTransport = nodemailer.createTransport(
smtpTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
jsonTransport: true,
auth: {
user: 'sender.example@gmail.com',
pass: '123123',
},
})
);
smtpTransport.use('compile', base64ToS3());
const templateWrapper = new Email({
transport: smtpTransport,
send: true,
preview: true,
views: {
options: {
extension: 'ejs',
},
root: path.join(__dirname, 'email/html/events'),
},
juice: true,
juiceSettings: {
tableElements: ['TABLE'],
},
juiceResources: {
preserveImportant: true,
webResources: {
relativeTo: path.join(__dirname, 'email/assets'),
images: true,
},
},
});
这是我的 HTML 模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Efys - Welcome</title>
<style>
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: border-box;
}
body {
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 0.8rem;
line-height: 1.4;
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
.bg-brand-color-blue-dark {
background-color: #033e75;
}
.bg-brand-color-gold-light {
background-color: #f0ede6;
}
.bg-brand-color-gold-dark {
background-color: #d0a345;
}
.bg-white {
background-color: #ffffff;
}
.brand-color-gold-dark {
color: #d0a345;
}
.brand-color-gold-light {
color: #f0ede6;
}
.brand-color-blue-dark {
color: #033e75;
}
.text-color-white {
color: #ffffff;
}
.text-color-black {
color: #000000;
}
.display-block {
display: block;
}
.margin-top-0rem {
margin-top: 0;
}
.margin-top-1rem {
margin-top: 1rem;
}
.margin-top-2rem {
margin-top: 2rem;
}
.margin-bottom-2rem {
margin-bottom: 2rem;
}
.padding-full-1rem {
padding: 1rem;
}
.padding-full-2rem {
padding: 2rem;
}
.padding-top-2rem {
padding-top: 2rem;
}
.padding-bottom-5rem {
padding-top: 5rem;
}
.border-solid-black {
border: 1px solid #000000;
}
.border-radius-half {
border-radius: 0.5rem;
}
.border-radius-1rem {
border-radius: 1rem;
}
.whitespace {
white-space: normal;
}
.font-size-x1 {
font-size: 1rem;
}
.font-size-x2 {
font-size: 2rem;
}
a,
a:visited {
color: blue;
}
.text-decoration-none {
text-decoration: none;
}
ol {
padding-left: 15px;
}
p {
margin-top: 1rem;
margin-bottom: 0;
}
.strong {
font-weight: bold;
}
h3 {
margin-bottom: 0;
}
h3 + p {
margin-top: 0;
}
.inline-icon {
margin-right: 5px;
}
.flexbox {
display: flex;
}
.flex-row {
flex-direction: row;
}
.flex-nowrap {
flex-wrap: nowrap;
}
.flexbox .cell {
width: 50%;
}
.flexbox .cell:nth-child(2) {
text-align: right;
}
.maximum-width {
width: 100%;
max-width: 36.25rem;
margin: 0 auto;
}
.logo {
width: 100%;
max-width: 36.25rem;
margin: 0 auto;
}
.logo img {
border: 0 none;
outline: 0 none;
width: 100%;
height: auto;
}
@media only screen and (max-width: 480px) {
.footer > .flexbox .cell {
width: 100%;
text-align: center;
}
.footer > .flexbox .cell:nth-child(2) {
text-align: center;
margin-top: 1rem;
}
.footer > .flex-nowrap {
flex-wrap: wrap;
}
.inner-cell.flexbox {
display: block;
max-width: 100%;
margin: 0 auto;
}
}
</style>
</head>
<body>
<div
class="wrapper display-block bg-brand-color-blue-dark padding-full-1rem"
>
<!-- logo -->
<div class="logo display-block" style="margin: 0 auto;">
<img
class="display-block"
src="efy-registration-header.jpg"
alt="abc def"
style="border-top-left-radius: 1rem; border-top-right-radius: 1rem;"
/>
</div>
<!-- content -->
<div
class="content display-block maximum-width bg-white text-color-black padding-full-2rem"
style="border-bottom-left-radius: 1rem; border-bottom-right-radius: 1rem;"
>
<p class="strong">Dear <%= clientName %>,</p>
<p>
You have successfully registered for <%= efyTitle %> on <%= efyDay %> at <%= startTime %>
</p>
<p>Your Reference ID is: <%= referenceId %></p>
<% if (displayAddress) { %>
<p>Zoom link: <%= address %></p>
<% } else { %>
<p>
Zoom link: You should receive an email update with the link to the
live efy
</p>
<% } %>
<h3>Zoom Instructions</h3>
<p>To join a Zoom meeting on a computer or mobile device:</p>
<ol>
<li>
Download the Zoom app from their Download Center
<a href="https://zoom.us/download" target="_blank"
>https://zoom.us/download</a
>. Otherwise, you will be prompted to download and install Zoom when
you click a join link.
</li>
</ol>
</div>
<!-- footer -->
<div
class="footer maximum-width text-color-white"
style="margin: 1rem auto 5rem;"
>
<div
class="flexbox flex-row flex-nowrap"
style="justify-content: center; align-items: flex-end;"
>
<div class="cell">
<div class="flexbox flex-row flex-nowrap inner-cell">
<div class="col" style="margin-right: 0.5em;">
<img
src="logo_icon.png"
alt="abc def"
width="50"
height="auto"
/>
</div>
<div class="col">
Villa 1, Alwasl Rd. <br />
Alsafa 2 <br />
Dubai, United Arab Emirates
</div>
</div>
<p>
<span class="strong brand-color-gold-dark">T.</span>
<a
href="tel:+97143809298"
class="text-decoration-none strong"
style="color: #FFFFFF;"
>+971 (0)4 380 9296</a
>
</p>
<p class="margin-top-0rem">
<span class="strong brand-color-gold-dark">E.</span>
<a
href="mailto:info@example.com"
class="text-decoration-none strong"
style="color: #FFFFFF;"
>info@example.com</a
>
</p>
</div>
<div class="cell">
<p>
<span class="inline-icon"
><a href="#"
><img
src="icon-facebook.png"
width="40"
height="auto"/></a
></span>
<span class="inline-icon"
><a href="#"
><img
src="icon-twitter.png"
width="40"
height="auto"/></a
></span>
<span class="inline-icon"
><a href="#"
><img
src="icon-instagram.png"
width="40"
height="auto"/></a
></span>
<span class="inline-icon"
><a href="#"
><img
src="icon-linkedin.png"
width="40"
height="auto"/></a
></span>
</p>
<p class="brand-color-gold-dark strong">@example.com</p>
<p class="margin-top-0rem">
<span class="strong brand-color-gold-dark">W.</span>
<a
href="//example.com"
class="text-decoration-none strong"
style="color: #FFFFFF;"
>example.com</a
>
</p>
</div>
</div>
</div>
</div>
</body>
</html>
当您加载 HTML 页面并使用如下图片时
<img
src="icon-linkedin.png"
width="40"
height="auto"
/>
它实际上告诉浏览器,从加载 HTML 页面的同一目录加载图像。
问题来了。当您的电子邮件在 Gmail
中加载时,它也会告诉浏览器相同的信息,并且浏览器将无法找到该图像。
解法:
如果您是从后端发送的。然后上传任意publicurl中的图片。您可以在前端托管中上传图片并找到 link。然后直接使用link。您的图片需要 public 才能访问。
如果您没有任何其他选择或托管。在任何 public github/gitlab 存储库中上传图像并使用 link.
According to the docs for nodemailer-base64-to-s3
,需要在base64ToS3
方法中传入一些配置选项。它说 aws/params/Bucket
是必需的。
我相信以下内容应该会给您一个良好的开端:
smtpTransport.use('compile', base64ToS3({
aws: {
params: {
Bucket: "bucket_name_here"
}
}
}));
另一个例子见https://github.com/forwardemail/nodemailer-base64-to-s3/blob/master/example.js。