Salesforce email templates work beautifully until you use them for custom object email merge fields.
And the problem isn’t with your code or template. It’s Salesforce’s architecture.
They have a specific requirement that they only play nice with Contact, Lead, and User objects, but not with custom objects.
If you’re facing this same problem, follow this guide to send email templates with custom object data.
Why doesn’t Merge Fields from Custom Objects work?
Salesforce email templates are tightly coupled to TargetObjectId and WhatId relationships. These determine who receives the email, and it only accepts IDs from standard objects like:
- Contact
- Lead
- User
- Opportunity
- Case
So when you try to merge fields from custom objects in an email template, Salesforce doesn’t know what to do. That’s why it renders empty even though the records exist.
To make merge fields work, we have to:
- Create a relationship bridge
- Create records in custom objects
- Build Your Email Template with Custom Object Merge Field
- Create an Apex Class to send an email
Once those three pieces align, Salesforce will render the merge data normally.
Step 1: Create a Custom Object Relationships
First, you need a custom object. For this example, I’ll create one called Training_Registration__c that tracks employee training sessions.
Go to Setup → Object Manager → Create → Custom Object
Name it whatever makes sense for your business case. Next, the most crucial step is where you need ot add a Lookup field that points to Contact, Lead, or User. Let’s see how you can add a Lookup Relationship:
- Click into your custom object
- Navigate to Fields & Relationships
- Click New
- Select Lookup Relationship
- Choose Contact as the related object
- Name it something like ContactRelationship__c
Now, here this tells Salesforce that your custom object record is connected to the contact record.
Important note: You can create up to 25 Lookup fields and 2 Master-Detail relationships on a single custom object.

Step 2: Create Records of Custom Object with Sample Data
Further, add a test record to your custom object and fill in the relationship field with an actual Contact.

Step 3: Build Your Email Template with Custom Object Merge Fields
This is where things get interesting. Head over to Setup → Email → Classic Email Templates.
Click New Template and create a Text or Custom (HTML) template.
Go to Setup → Email → Classic Email Templates. Click New Template and create a Text or Custom (HTML) template.

4. Create an Apex Class to send an email
Here we are creating an Apex class, CustomObjectEmailExample, which will be called from a Visualforce page. You can utilize it according to your business scenario.
CustomObjectEmailExample Class
/**
* Webkul Software.
*
* @category Webkul
* @author Webkul
* @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
public class CustomObjectEmailExample {
public PageReference sendingMail() {
Messaging.SingleEmailMessage mail = new
Messaging.SingleEmailMessage();// create instance of
SingleEmailMessage class
String[] sendingToBccAdd = new String[]
{'[email protected]'}; // Add email addresses to blind
carbon copy (BCC) addresses. The maximum allowed is 25.
mail.setBccAddresses(sendingToBccAdd);
String[] sendingTocAdd = new String[]{'[email protected]'};
// add addresses to carbon copy(CC). The maximum allowed is 25.
mail.setCcAddresses(sendingTocAdd);
mail.setReplyTo(userinfo.getUserEmail());
mail.setTargetObjectId('xxxxxxxxxxx');// This is the ID of rel
mail.setSaveAsActivity(false);
mail.setWhatId('XXXXXXXXXXXXXXXXX');// This is the record ID
mail.setTemplateId(template);// This is template ID
mail.setSenderDisplayName(userinfo.getname());
Messaging.sendEmail(mail);
return null;
}
}
Visualforce Page: sendEmail Page
/**
* Webkul Software.
*
* @category Webkul
* @author Webkul
* @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
<apex:page controller="CustomObjectEmailExample">
<apex:form >
<apex:commandButton value="Send Email" action="{!sendingMail}"/>
</apex:form>
</apex:page>
5. The Output of Example

Final Thoughts
It’s not Salesforce’s fault if the email template merge field is not working. It’s just how Salesforce’s email engine is designed.
And once the relationship chain is correct, the system behaves according to you.
The steps could work for any custom objects you make. Whether you want to send invoices, personalized messages, or anything else, the pattern stays the same.
Support
Need help implementing this in your org? Our Salesforce consulting team has built email automation for hundreds of companies across every industry imaginable. Or
Raise a ticket to let us know about your custom requirements.
Supported Framework Version - 45

Be the first to comment.