---
title: "LWC as a quick action"
url: "https://trailassembly.com/lwc-quick-actions/"
topic: "LWC and Front-End"
published: "2026-09-18T11:36:47+00:00"
updated: "2026-10-06T13:58:09+00:00"
---

# LWC as a quick action

**The quick version:** an LWC can be a quick action in two shapes. A screen action opens your component in a [modal](https://trailassembly.com/lwc-modals-and-lightning-modal/) and you close it yourself with `CloseActionScreenEvent`. A headless action renders nothing and runs an `@api invoke()` method when the button is clicked. Both are declared in the component’s meta file with the `lightning__RecordAction` target, and both are object-specific: a global quick action cannot be an LWC.

## Declaring it

The meta XML decides which shape you get.

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

`ScreenAction` gives a modal. `Action` gives a headless action. Leave the `targetConfig` out entirely and you get the screen behaviour by default, which is fine but worth stating explicitly so the next person does not have to guess.

After deploying, the action still has to be created in Setup on the object, with type Lightning Web Component, and then added to the page layout or the Lightning record page’s highlights panel. Deploying the component alone puts nothing in front of a user.

## Screen actions

Your component’s template renders inside a modal the platform provides. You do not write the header, the backdrop or the close button.

```apex
import { LightningElement, api } from 'lwc';
import { CloseActionScreenEvent } from 'lightning/actions';

export default class LogVisit extends LightningElement {
    @api recordId;
    @api objectApiName;

    handleCancel() {
        this.dispatchEvent(new CloseActionScreenEvent());
    }

    async handleSave() {
        await createVisit({ accountId: this.recordId, notes: this.notes });
        this.dispatchEvent(new CloseActionScreenEvent());
    }
}
```

The action’s label comes from the quick action definition in Setup, not from your component. The modal sizes itself to your content, so put your own container and SLDS spacing around it rather than expecting a standard layout.

Nothing closes the modal automatically. If your save path forgets to dispatch `CloseActionScreenEvent`, the user is left staring at a form that already submitted, and they will click Save again. Dispatch it on cancel, on success, and after a navigation.

Be careful with the order when you both navigate and close. Fire the navigation first and the close second, otherwise the modal can persist over the destination page.

## Headless actions

No template content is rendered. The platform calls `invoke()` each time the button is clicked.

```apex
<targetConfig targets="lightning__RecordAction">
    <actionType>Action</actionType>
</targetConfig>
```

```apex
export default class MarkReviewed extends LightningElement {
    @api recordId;

    @api async invoke() {
        try {
            await markReviewed({ recordId: this.recordId });
            this.dispatchEvent(new ShowToastEvent({
                title: 'Marked as reviewed', variant: 'success' }));
            getRecordNotifyChange([{ recordId: this.recordId }]);
        } catch (error) {
            this.dispatchEvent(new ShowToastEvent({
                title: 'Could not update the record',
                message: reduceErrors(error).join(', '),
                variant: 'error', mode: 'sticky' }));
        }
    }
}
```

The method must be called `invoke`, must be decorated `@api`, and takes no arguments. The component’s HTML file should exist but render nothing.

Two rules that follow from there being no screen. Always tell the user something happened, because a button that appears to do nothing gets clicked repeatedly. And always refresh the record, since the page will not notice your update on its own; `getRecordNotifyChange` from `lightning/uiRecordApi` tells [Lightning Data Service](https://trailassembly.com/lwc-stale-data-after-save/) to revalidate.

Nothing stops the user clicking twice while the call is in flight. If the operation is not [idempotent](https://trailassembly.com/callout-retries-and-idempotency/), guard it in Apex rather than in JavaScript.

## Picking between them

Headless when the action takes no input and the outcome is obvious: mark as reviewed, generate a document, send for approval where the approver is already determined. The user gets one click instead of a modal they have to dismiss.

Screen when you need input, a confirmation, or a summary of what is about to happen. Also screen when the operation is destructive, because the modal is the confirmation step.

Before writing either, check whether a standard action already does it. Update a field on the record and a standard Update Record action configured in Setup needs no code at all.

## Frequently asked

**Can an LWC be a global quick action?** No. LWC quick actions are object-specific record actions. For a global action, use a [screen flow](https://trailassembly.com/screen-flow-validation/) or an [Aura component](https://trailassembly.com/aura-to-lwc-migration-order/).

**How do I control the modal width?** You cannot set it directly for a quick action. Style your own container inside it.

**Do quick actions work in the mobile app?** Generally yes on record pages, and layout assumptions that hold on a desktop often do not. Test on a device.

**Why is my action missing from the layout?** The component must be exposed with the record action target, and the action must be added to the layout’s Salesforce Mobile and Lightning Experience Actions section.

---

Source: https://trailassembly.com/lwc-quick-actions/
Trail Assembly — independent Salesforce write-ups.
