Trigger Context Variables — What You Need to Know

When you write Apex triggers, the magic comes from the built-in Trigger context variables. These are the values Salesforce provides automatically, and they tell your code what is happening.

If you already know how to loop over Trigger.new, the next step is understanding how to use Trigger.isInsert, Trigger.isUpdate, Trigger.newMap, and the rest.

Trigger context variables — the core ones

Why these variables matter

They let you write a single trigger that handles multiple events safely. Without them, you would not know whether the code is inserting, updating, or deleting records.


trigger OpportunityTrigger on Opportunity (before insert, before update, after update, after delete) {
    if (Trigger.isBefore) {
        handleBefore(Trigger.new);
    }

    if (Trigger.isAfter) {
        handleAfter(Trigger.new, Trigger.oldMap);
    }
}
  

Common patterns

Use Trigger.new for new/changed values

In before insert and before update, Trigger.new contains the records you can modify. That is the place to add validation, normalization, and default values.


for (Opportunity opp : Trigger.new) {
    if (opp.CloseDate == null) {
        opp.addError('Close Date is required');
    }
}
  

Use Trigger.old to compare past values

When updating or deleting records, Trigger.old gives you the original values before the change. This is important for change detection and audit-like logic.


for (Opportunity opp : Trigger.new) {
    Opportunity oldOpp = Trigger.oldMap.get(opp.Id);
    if (oldOpp.StageName != opp.StageName) {
        // Stage changed
    }
}
  

Example: insert vs update in one trigger


trigger OpportunityStageTrigger on Opportunity (before insert, before update) {
    if (Trigger.isInsert) {
        for (Opportunity opp : Trigger.new) {
            opp.StageName = 'Prospecting';
        }
    }

    if (Trigger.isUpdate) {
        for (Opportunity opp : Trigger.new) {
            Opportunity oldOpp = Trigger.oldMap.get(opp.Id);
            if (oldOpp.StageName != opp.StageName) {
                // Do something when stage changes
            }
        }
    }
}
  

Quick context reference

Best practice

Always write trigger logic with bulk records in mind. Trigger.new may contain many records, so never assume only one record is present.

Use methods like handleBefore or handleAfter to keep the trigger body clean and readable.

← Back to Apex