Create A Deep Clone Using Headless Actions In Lightning Web Components LWC

A headless quick action performs custom code within a Lightning web component, distinct from a screen action that does not open a modal window. In essence, if you aim to execute custom logic, particularly via Apex, triggered by a quick action button click, headless actions in LWC offer a solution.

Here are a few examples/use cases illustrating when headless actions can be implemented:

  • Creating a custom clone button with deep clone functionality.
  • Implementing a custom approval button.
  • Submitting data to an external system.
  • Enhancing the record with details from an external system, and so forth.

Set up a component for quick actions.

Incorporate a Lightning web component into quick actions by specifying the component’s metadata. For utilizing an LWC as a headless action, include the following XML in the meta XML file. It’s important to note that the <actiontype> should be set to “Action” for a headless quick action. If you prefer to enable the component as a regular screen popup, include actionType as “ScreenAction”.

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
   <apiVersion>52.0</apiVersion>
   <isExposed>true</isExposed>
   <targets>
       <target>lightning__RecordAction</target>
   </targets>
    <targetConfigs>
   <targetConfig targets="lightning__RecordAction">
     <actionType>Action</actionType>
   </targetConfig>
 </targetConfigs>
</LightningComponentBundle>

Execution

With the setup in place, the necessary custom logic should be implemented within the JavaScript file of the LWC. The HTML file can remain empty, containing only the template tags.

In your Lightning web component, declare invoke() as a public method. The invoke() method is triggered each time the quick action is executed.

import { LightningElement, api } from "lwc";
 
export default class HeadlessSimple extends LightningElement {
  @api invoke() {
    console.log("This is a headless action.");
  }
}

Illustrative Scenario

Now, if you intend to employ a deep clone logic from the quick action button, the code appears as follows.

import { LightningElement, api } from "lwc";
import { ShowToastEvent } from 'lightning/platformShowToastEvent'
import { NavigationMixin } from 'lightning/navigation';
import startDeepClone from '@salesforce/apex/ROR_CloneController.startDeepClone';
 
export default class Ror_deepcloneaction extends NavigationMixin(LightningElement) {
 
    @api invoke() {
        this.startToast('Deep Clone!','Starting cloning process...');
        //Call the cloning imperative apex js method
        this.startCloning();
    }
     
    startCloning(){
        startDeepClone({recordId: this.recordId})
        .then(result => {
            this.startToast('Deep Clone!','Cloning Process Completed');
            this.navigateToRecord(result);
         })
         .catch(error => {
            this.startToast('Deep Clone!','An Error occured during cloning'+error);
         });
    }
 
    startToast(title,msg){
        let event = new ShowToastEvent({
            title: title,
            message: msg,
        });
        this.dispatchEvent(event);
    }
 
    navigateToRecord(clonedRecId){
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                recordId: clonedRecId,
                actionName: 'view',
            },
        });
    }
 
}

Upon clicking the quick action button, the invoke method is triggered, subsequently initiating the imperative Apex call. This call involves the cloning process, and upon completion, it returns the ID of the newly cloned record. A successful return from the Apex is followed by utilizing an event to notify the user, and the NavigationMixin is employed to redirect the user to the cloned record.