In Salesforce, we can create a custom quick action to perform tasks like creating records, updating fields, or triggering custom logic directly from a record page. In this Salesforce tutorial, we will learn how to create quick actions with lightning web components in Salesforce.
LWC Quick Actions in Salesforce
To create a Quick Action with LWC, we first create an LWC component, then configure it in the meta.xml file by specifying lightning__RecordAction or lightning__GlobalAction as targets, and then add it to a Salesforce page. These actions perform tasks like form submissions, record updates, or any actions that can be called through button actions.
Create Quick Actions With Lightning Web Components
In Salesforce, using the Lightning Web Components, we can create two types of actions.
1. Screen Quick Actions: When triggered, these actions display a custom user interface in a modal window. They are ideal for scenarios where user input is required, such as performing tasks like creating or editing records directly within the model.
2. Headless Quick Actions: These actions execute custom logic without displaying a modal screen. They are triggered by a button click and run the JavaScript code defined in the LWC using the @api invoke() method to define the action. These actions are used for tasks that don’t require user interaction, such as updating a record, navigating to another page, or dispatching an event.
Create Screen Quick Actions Using Lightning Web Components
In the example below, we will create a quick action, “Send Payment Reminder”. This quick action will be added to the Opportunity object record page. When clicked, it will display a screen to confirm sending a payment reminder to the Opportunity’s primary contact via a custom Apex method.
Follow the steps below to create a quick action with Lightning Web Components.
- First, create a controller class from which we will fetch the opportunity details for various field values.
public with sharing class PaymentReminderController {
@AuraEnabled
public static String sendPaymentReminder(String opportunityId) {
Opportunity opp = [SELECT Name, Amount, CloseDate, Account.Name
FROM Opportunity
WHERE Id = :opportunityId
LIMIT 1];
System.debug('Payment reminder sent for Opportunity: ' + opp.Name);
return 'Payment reminder sent successfully for ' + opp.Name;
}
}
}We will deploy this LWC component as an action, so we kept the limit as one to fetch the current Opportunity record ID.
- Create an LWC component and enter the code below in the HTML file.
This will create a modal popup for the “Send Payment Reminder” action and display the opportunity details. In the footer, the Send Reminder button triggers an Apex method for sending the reminder.
<template>
<lightning-modal-header label="Send Payment Reminder"></lightning-modal-header>
<lightning-modal-body>
<template if:true={isLoading}>
<p>Loading Opportunity details...</p>
</template>
<template if:false={isLoading}>
<template if:true={opportunity}>
<p>Send a payment reminder for the following Opportunity:</p>
<lightning-card title={opportunity.fields.Name.value}>
<div class="slds-p-around_small">
<p><strong>Amount:</strong> {opportunity.fields.Amount.value}</p>
<p><strong>Close Date:</strong> {formattedCloseDate}</p>
<p><strong>Account:</strong> {opportunity.fields.Account.value.fields.Name.value}</p>
</div>
</lightning-card>
<p>Are you sure you want to proceed?</p>
</template>
<template if:false={opportunity}>
<p>No Opportunity data available.</p>
</template>
</template>
</lightning-modal-body>
<lightning-modal-footer>
<lightning-button label="Cancel" onclick={handleCancel}></lightning-button>
<lightning-button label="Send Reminder" variant="brand" onclick={handleSend}></lightning-button>
</lightning-modal-footer>
</template>- To define the logic of sending remainder to the opportunity name, enter the below code in the JS file.
The code below contains the logic for fetching Opportunity data using getRecord from lightning/uiRecordApi for handling user interactions and ShowToastEvent to display notifications.
import { LightningElement, api, wire } from 'lwc';
import LightningModal from 'lightning/modal';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import sendPaymentReminder from '@salesforce/apex/PaymentReminderController.sendPaymentReminder';
import OPP_NAME from '@salesforce/schema/Opportunity.Name';
import OPP_AMOUNT from '@salesforce/schema/Opportunity.Amount';
import OPP_CLOSEDATE from '@salesforce/schema/Opportunity.CloseDate';
import OPP_ACCOUNT_NAME from '@salesforce/schema/Opportunity.Account.Name';
export default class SendPaymentReminder extends LightningModal {
@api recordId;
opportunity = null;
isLoading = true;
@wire(getRecord, {
recordId: '$recordId',
fields: [OPP_NAME, OPP_AMOUNT, OPP_CLOSEDATE, OPP_ACCOUNT_NAME]
})
wiredOpportunity({ error, data }) {
this.isLoading = false;
if (data) {
this.opportunity = data;
} else if (error) {
this.opportunity = null;
this.showToast('Error', 'Failed to load Opportunity: ' + error.body.message, 'error');
this.close();
}
}
get formattedCloseDate() {
if (this.opportunity) {
const closeDate = getFieldValue(this.opportunity, OPP_CLOSEDATE);
return new Date(closeDate).toLocaleDateString();
}
return '';
}
handleCancel() {
this.close();
}
async handleSend() {
try {
const result = await sendPaymentReminder({ opportunityId: this.recordId });
this.showToast('Success', result, 'success');
this.close();
} catch (error) {
this.showToast('Error', error.body.message, 'error');
}
}
showToast(title, message, variant) {
const event = new ShowToastEvent({
title: title,
message: message,
variant: variant
});
this.dispatchEvent(event);
}
}In this, we used the @api decorator to receive the record ID of the current Opportunity. The wired function wiredOpportunity fetches the Opportunity data using getRecord.
If the data retrieval is successful, it updates the component state, making the Opportunity details available for display. After this, the handleSend() function calls the Apex method (sendPaymentReminder), passing the recordId as a parameter.
At last, the ShowToastEvent will display a success or error toast message.
- To make this LWC component a quick action for an object, enter the code below in the meta.xml file inside the Lightning Component Bundle tag.
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordAction</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordAction">
<actionType>ScreenAction</actionType>
</targetConfig>
</targetConfigs>With the <actionType> ScreenAction tag, we have defined that this action will be a screen action, which means that the action will open a modal window on the screen.
- After this, deploy the LWC component to the org. Right-click on the component and select SFDX: Deploy this source to org.
- Now, we need to create a quick action and integrate the LWC component with it.
To create quick action, go to the Object Manager setup > Select the Opportunity object > Buttons, Links, and Actions > New Action.

- In the new action, select the action type as Lightning Web Component, and then in the next field, select the Lightning Web Component that we have created.
For the label, you can either select from the standard label type or enter a custom label in the Label field.
At last, click on the Save button.

- Navigate to the object page layout and select Mobile & Lightning Actions. Then, drag and drop the LWC quick action to the Mobile and Lightning Experience Actions and save the changes.

- Go to the Opportunity object record page. The LWC quick action that we created will be displayed in the quick action button.
If it is not visible in the action button, click on the dropdown near the action buttons and select it from there.

As we click on the quick action, it will display a pop-up modal with opportunity details, here click on the button send remainder.
If the remainder is sent successfully, it will display a success toast message on the screen.

This way, we can create quick actions with Lightning Web Components in Salesforce by following the above steps.
Headless Quick Actions Using Lightning Web Components
In Salesforce, quick actions, unlike Screen Actions, which display a modal, Headless Actions execute logic in the background without displaying anything on the screen. These quick actions are used to perform automated tasks that run in the background, such as sending an email.
This can be implemented directly using JavaScript code, and hence, it does not require the HTML file in the LWC Component. To implement the headless action, we call the invoke () method, and it should be exposed as a public method.
Create Headless Quick Actions With Lightning Web Components in Salesforce
In the example below, we will create a headless action on the Lead object to convert a Lead to an Opportunity with a button click.
The standard Lead convert quick action opens a window where you have to define other details and select the object type before lead conversion, but with this headless quick action, the lead will be converted with a single click.
- Create an LWC component convertLead and enter the code below in the JS file.
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import convertLeadToOpportunity from '@salesforce/apex/LeadConverter.convertLeadToOpportunity';
export default class ConvertLead extends LightningElement {
@api recordId;
@api invoke() {
convertLeadToOpportunity({ leadId: this.recordId })
.then(result => {
if (result === 'Success') {
this.showToast('Success', 'Lead converted to Opportunity!', 'success');
} else {
this.showToast('Error', 'Failed to convert Lead: ' + result, 'error');
}
})
.catch(error => {
this.showToast('Error', 'An error occurred: ' + error.body.message, 'error');
});
}
showToast(title, message, variant) {
const event = new ShowToastEvent({
title: title,
message: message,
variant: variant
});
this.dispatchEvent(event);
}
}In the above code, the @api recordId will get the current record (lead) ID, and @api invoke will trigger the quick action when it is called through the button click.
To convert the lead to an opportunity, it will call the apex class method convertLeadToOpportunity, which we will define in the next step. To show proof of lead conversion, I have also added the Toast notification feature, which will display a success message on lead conversion.
Since this quick action runs in the background, we don’t need to define the UI in the HTML file, and you can even delete this HTML file from the LWC component.
- Enter the code below in the meta.xml file to enable the component to be deployed as a quick action on the Lightning page.
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordAction</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordAction">
<actionType>Action</actionType>
</targetConfig>
</targetConfigs>With <target>lightning__RecordAction</target>, we have defined this component available to the quick actions, and with <actionType>Action</actionType>, we set this quick action as a headless action.
- The headless action runs in the background and relies on Apex for server-side logic, like converting a Lead. Create an Apex class LeadConverter and enter the code below to handle the lead-to-opportunity conversion.
public with sharing class LeadConverter {
@AuraEnabled
public static String convertLeadToOpportunity(Id leadId) {
try {
Lead leadRecord = [SELECT Id, Company, LastName FROM Lead WHERE Id = :leadId LIMIT 1];
Database.LeadConvert lc = new Database.LeadConvert();
lc.setLeadId(leadId);
lc.setOpportunityName(leadRecord.Company + ' - ' + leadRecord.LastName + ' Opportunity');
lc.setConvertedStatus('Closed - Converted');
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted = true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);
Database.LeadConvertResult lcr = Database.convertLead(lc);
if (lcr.isSuccess()) {
return 'Success';
} else {
return 'Conversion failed';
}
} catch (Exception e) {
throw new AuraHandledException('Error converting Lead: ' + e.getMessage());
}
}
}This class method will convert the lead to an opportunity using Database.convertLead, and set the Opportunity Name based on the Lead’s company and Last Name.
- Create a quick action for the Lead object and configure it the same way we have done for the screen action.
Navigate to the Lead tab and open the lead record. On the lead record page, click on the quick action button. A success message will be displayed after a successful lead conversion.

Navigate to the Opportunity tab to view the converted lead. There, you will see that the lead information is configured according to the logic of the Apex controller class.

This way, we can create headless quick actions with Lightning Web Components in Salesforce.
Conclusion
In this Salesforce tutorial, we discussed the LWC quick action and learned how to create one in Salesforce and deploy it on the page layout to make it accessible to the user on the object record page.
In the above example, we created an LWC component that sends a reminder to the Opportunity’s primary contact and displays a toast message when it successfully sends the reminder.
After this, we also created a headless quick action to convert the lead to an opportunity. Then, we integrated the LWC component with the Lightning quick action from the object setup.
You may also like to read:
- Decorators in Salesforce Lightning Web Component(LWC)
- Add a Picklist In LWC Data Table
- Add Related Fields Columns in Salesforce LWC Data Table
- Display a Checkbox field in LWC Data Table
- Build a Custom Object LWC Data Table in Salesforce
I am Bijay Kumar, the founder of SalesforceFAQs.com. Having over 10 years of experience working in salesforce technologies for clients across the world (Canada, Australia, United States, United Kingdom, New Zealand, etc.). I am a certified salesforce administrator and expert with experience in developing salesforce applications and projects. My goal is to make it easy for people to learn and use salesforce technologies by providing simple and easy-to-understand solutions. Check out the complete profile on About us.