I try to send an account activation email through Java/Spring Boot Email Service, but the logo image is not displayed on Gmail. (ofc on localhost everything is fine). The image is being sent as an attachment to the email correctly, but it isn't displayed in the email.
I use a static activation-mail.html
, where I try to display it like this:
<div class="logo">
<img src="cid:logo" alt="Logo" style="max-width: 250px;"/>
</div>
I use this method in EmailConfiguration.java
:
public void sendMailWithInlineImage(String recipientEmail,
String contentHtml,
String subject,
byte[] imageBytes,
String contentId,
String contentType,
boolean onCreate)
throws MessagingException {
if (session == null) {
refreshSession();
}
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(email));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail));
message.setSubject(subject, StandardCharsets.UTF_8.name());
MimeBodyPart htmlPart = new MimeBodyPart();
htmlPart.setContent(contentHtml, "text/html; charset=UTF-8");
ByteArrayDataSource ds = new ByteArrayDataSource(imageBytes, contentType);
ds.setName("logo.png");
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.setDataHandler(new DataHandler(ds));
imagePart.setContentID("<" + contentId + ">");
imagePart.setDisposition(MimeBodyPart.INLINE);
imagePart.setFileName("logo.png");
imagePart.setHeader("Content-Type", contentType + "; name=logo.png");
MimeMultipart multipart = new MimeMultipart("related");
multipart.addBodyPart(htmlPart);
multipart.addBodyPart(imagePart);
message.setContent(multipart);
Transport.send(message);
} catch (MessagingException ex) {
if (onCreate) {
refreshSession();
sendMailWithInlineImage(recipientEmail, contentHtml, subject,
imageBytes, contentId, contentType, false);
} else {
throw ex;
}
}
}
and this in EmailService.java
:
public void sendActivation(User user) {
log.info("--START sendActivation");
try {
String html = Files.toString(activeTemplate.getFile(), Charsets.UTF_8);
html = html.replace("https://google.com", fontendUrl + "/activate/" + user.getUuid());
byte[] logoBytes = Files.toByteArray(logoResource.getFile());
emailConfiguration.sendMailWithInlineImage(
user.getEmail(),
html,
"Aktywacja konta",
logoBytes,
"logo",
"image/png",
true
);
} catch (IOException | MessagingException e) {
log.error("Błąd wysyłania maila", e);
throw new RuntimeException(e);
}
log.info("--STOP sendActivation");
}
the path to logo.png is: resources/static/img/logo.png
I also have this warning in IntelliJ Idea in the .html file:
ps. I also tried to display the logo using imgur hosting etc. but the result was identical.
If you only want to appeared a logo on email then Embed the Image as a Base64 Data URI (Less Recommended for Large Images). You can embed the image directly into the HTML as a Base64 encoded string. This eliminates the need for an external URL.
Convert the image to Base64:
Use an online tool (like https://www.base64-image.de/(opens in a new tab)) or a programming language to convert your image to a Base64 string.
Embed the Base64 string in the src attribute:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w+gYQQAAZIAA8jQXYgAAAABJRU5ErkJggg==" alt="Logo" style="max-width:250px;">
(Replace the example Base64 string with your actual image's Base64 data.)
Pros: No external HTTP requests.
Cons:
Increases email size: Base64 encoding makes the image data larger, which can increase email size and potentially trigger spam filters.
Not suitable for large images: Embedding large images as Base64 can significantly increase email size and slow down rendering.
Can be less efficient: Some email clients might not handle Base64 images as efficiently as regular images.
Use this method only for very small images (e.g., small icons).