Create Headless Quick Actions

A headless quick action executes custom code in a Lightning web component. Unlike a screen action, a headless action doesn’t open a modal window.

To enable your component to be used as a headless quick action, configure a target. See Configure a Component for Quick Actions.

Unlike other Lightning web components on record pages, LWC quick actions don’t pass in recordId in connectedCallback(). If you need access to recordId, set the value of recordId in your code.

1_recordId;
2
3@api
4get recordId() {
5    return this._recordId;
6}
7
8set recordId(recordId) {
9    if (recordId !== this._recordId) {
10        this._recordId = recordId;
11   }
12}

Implement invoke() 

In your Lightning web component, always expose invoke() as a public method for headless quick actions. The invoke() method executes every time the quick action is triggered.

1import { LightningElement, api } from "lwc";
2
3export default class HeadlessSimple extends LightningElement {
4  @api invoke() {
5    console.log("Hi, I'm an action.");
6  }
7}

Create an empty template for your Lightning web component.

1<template> </template>

To prevent the quick action from being executed multiple times in parallel in long-running actions, add an internal boolean flag.

The return type of invoke() is void. Returning a Promise makes your method asynchronous, but the returned Promise is ignored.

This code uses a boolean flag to block a double execution and a Promise to wait for the sleep to finish. Even though the return type is void, the code executes asynchronously.

1import { LightningElement, api } from "lwc";
2
3export default class HeadlessAsync extends LightningElement {
4  isExecuting = false;
5
6  @api async invoke() {
7    if (this.isExecuting) {
8      return;
9    }
10
11    this.isExecuting = true;
12    await this.sleep(2000);
13    this.isExecuting = false;
14  }
15
16  sleep(ms) {
17    return new Promise((resolve) => setTimeout(resolve, ms));
18  }
19}

Navigate 

To navigate to another page, record, or list in Lightning Experience, use the navigation service.

This example navigates to the contact home page.

navigateToRecordHeadlessAction.js
1import { LightningElement, api } from 'lwc';
2import { NavigationMixin } from 'lightning/navigation';
3
4export default class NavigateToRecordHeadlessAction extends NavigationMixin(
5    LightningElement
6) {
7    @api invoke() {
8        this[NavigationMixin.Navigate]({
9            type: 'standard__objectPage',
10            attributes: {
11                objectApiName: 'Contact',
12                actionName: 'home'
13            }
14        });
15    }
16}

See Navigate to Pages, Records, and Lists.

Dispatch Events 

You can dispatch a custom event from a quick action. This example dispatches two toasts sequentially using the event provided by the lightning/platformShowToastEvent module.

dispatchEventHeadlessAction.js
1import { LightningElement, api } from 'lwc';
2import { ShowToastEvent } from 'lightning/platformShowToastEvent';
3
4export default class DispatchEventHeadlessAction extends LightningElement {
5    @api recordId;
6    @api async invoke() {
7        // Fire Toast message
8        let event = new ShowToastEvent({
9            title: 'I am a headless action!',
10            message: 'Hi there! Starting...'
11        });
12        this.dispatchEvent(event);
13        // Wait and fire another another Toast message
14        await this.sleep(2000);
15        // Fire Toast message
16        event = new ShowToastEvent({
17            title: 'I am a headless action on record with id ' + this.recordId,
18            message: 'All done!'
19        });
20        this.dispatchEvent(event);
21    }
22
23    sleep(ms) {
24        // eslint-disable-next-line @lwc/lwc/no-async-operation
25        return new Promise((resolve) => setTimeout(resolve, ms));
26    }
27}

See Toast Notifications and Communicate with Events.

See Also