You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js邮件模板图片无法加载:如何正确设置图片URL

Next.js邮件模板图片加载问题解决方案

问题重现

你在Next.js中制作邮件模板,通过字符串替换填充变量,代码如下:

const emailHTML = verifyEmailTemplate
  .replace('{{ subject }}', subject)
  .replace('{{ code }}', code)
  .replace('{{ logoURL }}', 'https://fakeURL.com/images/logo/logo-dark.png');

// 模板示例
const verifyEmailHTML = `
<table role="presentation" class="main">
    <!-- START MAIN CONTENT AREA -->
    <tr>
    <td class="wrapper">
        <table
        role="presentation"
        border="0"
        cellpadding="0"
        cellspacing="0"
        >
        <tr>
            <img
            class="logo"
            src="{{ logoURL }}"
            alt="Logo"
            />
        </tr>
...
`;

尝试外部URL、public目录图片、直接写入URL后,邮件中图片仍无法加载,想了解最佳实现方案。

核心问题排查与解决方案

1. 先确认URL的有效性

不管用外部URL还是public目录资源,必须保证URL是公网可直接访问的:

  • 外部URL:直接在浏览器打开该URL,确认能正常显示图片,检查是否有防盗链、权限验证(比如需要登录才能访问)。
  • public目录资源:Next.js的public目录资源会被部署到根路径,正确的URL格式是${process.env.NEXT_PUBLIC_APP_URL}/images/logo-dark.png,其中NEXT_PUBLIC_APP_URL是你的生产环境域名(开发时可设为http://localhost:3000,但测试邮件时要确保客户端能访问到这个地址,比如用ngrok暴露本地服务)。

2. 字符串替换的细节检查

  • 模板中的变量{{ logoURL }}要和替换代码中的字符串完全匹配,注意大小写、空格等拼写问题。
  • 替换后打印emailHTML,检查最终生成的HTML中img的src属性是否是正确的绝对路径,避免出现相对路径或错误的URL。

3. 外链vs嵌入图片的选择

外链(当前做法)

  • 优点:邮件体积小,图片维护方便(修改图片只需更新资源,不需要修改模板)。
  • 缺点:依赖外部资源可用性,且多数邮件客户端默认阻止加载外部图片,需要用户手动开启才能显示。
  • 适用场景:非核心图片,或能接受用户手动加载的场景。

嵌入图片(更稳妥的方案)

如果要确保图片直接显示,推荐使用嵌入方式:

  • Base64嵌入:将图片转成Base64字符串,直接写入src属性。在Next.js服务器端可以读取public目录的图片并转换:
    import fs from 'fs';
    import path from 'path';
    
    // 服务器端函数中执行
    const logoPath = path.join(process.cwd(), 'public', 'images', 'logo-dark.png');
    const logoBase64 = fs.readFileSync(logoPath, { encoding: 'base64' });
    const logoSrc = `data:image/png;base64,${logoBase64}`;
    
    // 替换模板中的变量
    const emailHTML = verifyEmailTemplate.replace('{{ logoURL }}', logoSrc);
    
    注意:Base64会使图片体积增大约30%,适合小尺寸图片(比如logo)。
  • CID嵌入:将图片作为邮件附件发送,设置Content-ID,HTML中通过CID引用。以nodemailer为例:
    import nodemailer from 'nodemailer';
    
    const transporter = nodemailer.createTransport({ /* 配置 */ });
    
    transporter.sendMail({
      from: 'your@email.com',
      to: 'recipient@email.com',
      subject: 'Verify Email',
      html: emailHTML.replace('{{ logoURL }}', 'cid:logo'),
      attachments: [
        {
          filename: 'logo-dark.png',
          path: path.join(process.cwd(), 'public', 'images', 'logo-dark.png'),
          cid: 'logo' // 和HTML中的cid对应
        }
      ]
    });
    

4. public目录资源的正确使用方式

  • 图片必须放在Next.js的public目录下,比如public/images/logo-dark.png。
  • 生成URL时必须使用绝对路径,不能用相对路径(比如/images/logo-dark.png),因为邮件客户端不在你的应用环境中,相对路径会失效。
  • 开发环境测试时,若使用localhost地址,需要确保邮件客户端能访问到你的本地服务器(同一局域网或用ngrok暴露公网地址)。

总结

  • 字符串替换的方式本身没问题,但要保证替换后的URL是公网可访问的绝对路径。
  • 若要确保图片必现,嵌入(Base64或CID)比外链更可靠;若追求轻量化,外链是可选方案。
  • public目录是可行的资源存储方案,但必须配合正确的绝对路径使用。

内容的提问来源于stack exchange,提问作者user23240484

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:58:32