Headless Quick Actions in Lightning Web Components

The Headless Quick Actions are a significant addition to the toolbox of Lightning Web Component developers. They allow you to execute custom code within a Lightning web component without opening a modal window, distinguishing them from traditional screen actions. This feature offers greater flexibility and control, enabling you to create more streamlined and efficient user experiences.

To enable your Lightning web component to function as a Headless Quick Action, you need to configure a target. This configuration file defines a headless action.

<?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>

One notable difference between LWC quick actions and other Lightning web components on record pages is the absence of the recordId in the connectedCallback(). If your code requires access to the recordId, you’ll need to set its value manually in your code.

_recordId;
set recordId(recordId) {
    if (recordId !== this._recordId) {
        this._recordId = recordId;
    }
}

Implementing the invoke() Method

In your Lightning web component, it’s essential to expose the invoke() method as a public method for Headless Quick Actions. The invoke() method is executed each time the quick action is triggered, making it a crucial part of your component’s functionality.

Here’s a simple example of an LWC component with the <strong>method:</strong>

import { LightningElement, api } from "lwc";

export default class HeadlessSimple extends LightningElement {
  @api invoke() {
    console.log("Hi, I'm an action.");
  }
}

Creating an Empty Template

In order to prevent the quick action from being executed multiple times in parallel during long-running actions, you should include an internal boolean flag. Although the return type of invoke() is void, it can be executed asynchronously by utilizing a Promise.

Here’s an example of using a boolean flag to ensure single execution and a Promise to manage asynchronous execution:

import { LightningElement, api } from "lwc";

export default class HeadlessAsync extends LightningElement {
  isExecuting = false;

  @api async invoke() {
    if (this.isExecuting) {
      return;
    }

    this.isExecuting = true;
    await this.sleep(2000); // Simulate a 2-second action
    this.isExecuting = false;
  }

  sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
}

Navigation with Lightning Experience

To navigate to another page, record, or list within the Lightning Experience, you can utilize the navigation service. The following example demonstrates how to navigate to the contact home page:

import { LightningElement, api } from "lwc";
import { NavigationMixin } from "lightning/navigation";

export default class NavigateToRecordAction extends NavigationMixin(LightningElement) {
  @api invoke() {
    this[NavigationMixin.Navigate]({
      type: "standard__objectPage",
      attributes: {
        objectApiName: "Contact",
        actionName: "home",
      },
    });
  }
}

Dispatching Custom Events

Headless Quick Actions provide the ability to dispatch custom events, enhancing the interaction and feedback within your components. In the following example, we dispatch two toasts sequentially using the event provided by the lightning/platformShowToastEvent module:

import { LightningElement, api } from "lwc";
import { ShowToastEvent } from "lightning/platformShowToastEvent";

export default class DispatchEventAction extends LightningElement {
  @api async invoke() {
    let event = new ShowToastEvent({
      title: "I am a headless action!",
      message: "Hi there! Starting...",
    });
    this.dispatchEvent(event);

    await this.sleep(2000); // Simulate a 2-second delay

    event = new ShowToastEvent({
      title: "I am a headless action!",
      message: "All done!",
    });
    this.dispatchEvent(event);
  }

  sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
}

Other user cases of headless quick action Below are a few additional scenarios along with examples and code snippets to illustrate how you can leverage this feature:

Data Validation and Error Handling

You can use headless quick actions to perform data validation and handle errors when users interact with records. For example, you might want to ensure that certain fields meet specific criteria before allowing a record update.

import { LightningElement, api } from 'lwc';

export default class DataValidationAction extends LightningElement {
    _recordId;
    set recordId(recordId) {
      if (recordId !== this._recordId) {
        this._recordId = recordId;
      }
    }
    @api
    async invoke(recordId) {
        // Retrieve the record data
        const record = await this.retrieveRecordData(recordId);

        // Validate data
        if (record && record.Field__c !== 'Valid Value') {
            this.displayValidationErrorToast();
        } else {
            // Perform the action if data is valid
            await this.performRecordUpdate(recordId);
        }
    }

    // Implement methods for data retrieval, update, and displaying toasts
}

Integration with External Services

Headless Quick Actions can be used to integrate with external services or APIs. This is especially useful when you need to synchronize data between Salesforce and external systems.

Dynamic Record Creation

You can use Headless Quick Actions to create new records dynamically based on certain conditions. For example, you might want to create a related record when a specific field is updated.

Custom Record Updates

You can implement custom logic for record updates based on specific criteria. For instance, you might want to update related records when a particular field is modified.

Conclusion

Headless Quick Actions in Lightning Web Components offer a powerful toolset for enhancing user experiences and executing custom code with precision. By configuring your component as a Headless Quick Action and implementing the invoke() method, you can streamline and optimize your development process. Additionally, you can seamlessly navigate to different pages and dispatch custom events, adding interactivity to your components. So, leverage these capabilities to their full potential and take your Lightning Web Component development to the next level.

About the blog

SFDCLessons is a blog where you can find various Salesforce tutorials and tips that we have written to help beginners and experienced developers alike. we also share my experience and knowledge on Salesforce best practices, troubleshooting, and optimization. Don’t forget to follow us on:

Newsletter

Subscribe to our email newsletter to be notified when a new post is published.

  • How To Create an Einstein Bot in Salesforce?
    Salesforce Einstein Bot is a multilingual, automated customer service tool that improves customer interactions and reduces costs.
  • Salesforce Classic Encryption for Custom Fields Explained
    Salesforce Classic Encryption for Custom Fields allows users to encrypt custom text fields and control access to sensitive information at no additional cost.
  • The 10 Must-Know LWC Wire Adapters in Salesforce
    Salesforce’s Lightning Web Components (LWC) has revolutionized UI development with Wire Service (Wire Adapters), enabling effective communication with the Salesforce platform. This post explores ten popular LWC wire adapters, which fetch and manipulate data efficiently.
  • The Magic of Lightning Web Components (LWC) Wire Adapter
    Salesforce LWC Wire Adapter streamlines data flow, enhances modularity, and ensures code quality through automatic updates and loose coupling principles.
  • Maximize User Interaction: GraphQL, LWC, and Toasts
    This blog proposes a solution for improving user experience in Salesforce development. It addresses the problem of unclear messages when users don’t have access to specific records. The solution includes using GraphQL for efficient data fetching, Lightning Web Components for a responsive interface, the onrowaction event in lightning-datatable for smoother interactions, and custom toast messages for clearer communication. These strategies aim to create efficient and user-friendly applications.

Arun Kumar

Arun Kumar is a Salesforce Certified Platform Developer I with over 7+ years of experience working on the Salesforce platform. He specializes in developing custom applications, integrations, and reports to help customers streamline their business processes. Arun is passionate about helping businesses leverage the power of Salesforce to achieve their goals.

Leave a Reply