Skip to main content

Overview

The @api decorator can expose methods as part of a component’s public API. Public methods allow parent components to call functions on child components, enabling child-to-parent communication patterns.
Public methods are typically used for imperative actions like refreshing data, opening modals, or resetting component state.

Basic Usage

Exposing a Public Method

Mark a method as public using the @api decorator:
// clock.js
import { LightningElement, api } from 'lwc';

export default class Clock extends LightningElement {
    timestamp = new Date();

    @api
    refresh() {
        this.timestamp = new Date();
    }
}
Source: force-app/main/default/lwc/clock/clock.js:6-9

Calling a Public Method

Access the child component using querySelector and call the method:
// apiMethod.js
import { LightningElement } from 'lwc';

export default class ApiMethod extends LightningElement {
    handleRefresh() {
        this.template.querySelector('c-clock').refresh();
    }
}
Source: force-app/main/default/lwc/apiMethod/apiMethod.js:4-6

Common Use Cases

1. Refresh Component Data

Refresh data displayed in a child component:
import { LightningElement, api } from 'lwc';

export default class DataTable extends LightningElement {
    data = [];

    @api
    async refresh() {
        // Fetch fresh data from server
        this.data = await this.fetchData();
    }
}

2. Reset Component State

Reset form or component state to initial values:
import { LightningElement, api } from 'lwc';

export default class CustomForm extends LightningElement {
    formData = {};

    @api
    reset() {
        this.formData = {};
        this.template.querySelector('form').reset();
    }
}

3. Focus Management

Programmatically set focus on an input element:
import { LightningElement, api } from 'lwc';

export default class CustomInput extends LightningElement {
    @api
    focus() {
        this.template.querySelector('input').focus();
    }
}

4. Screen Actions

Implement custom screen actions for Salesforce flows:
import { LightningElement, api } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class NavigateToRecordHeadlessAction extends NavigationMixin(LightningElement) {
    @api invoke() {
        this[NavigationMixin.Navigate]({
            type: 'standard__recordPage',
            attributes: {
                recordId: this.recordId,
                actionName: 'view'
            }
        });
    }
}
Source: Similar to force-app/main/default/lwc/navigateToRecordHeadlessAction/navigateToRecordHeadlessAction.js:7

Async Public Methods

Public methods can be async for asynchronous operations:
import { LightningElement, api } from 'lwc';

export default class AsyncComponent extends LightningElement {
    @api recordId;

    @api async invoke() {
        // Perform async operations
        await this.saveData();
        await this.dispatchEvent(new CustomEvent('complete'));
    }

    async saveData() {
        // Save data to server
        return new Promise(resolve => setTimeout(resolve, 1000));
    }
}
Source: Similar to force-app/main/default/lwc/dispatchEventHeadlessAction/dispatchEventHeadlessAction.js:6

Best Practices

Use public methods sparingly. Event-based communication is often more maintainable than directly calling child methods.

When to Use Public Methods

  • Imperative actions: Refreshing, resetting, focusing
  • Screen actions: Flow integration points
  • Utility functions: Reusable logic that doesn’t fit event patterns

When to Use Events Instead

  • Data flow: Sending data from child to parent
  • User interactions: Button clicks, form submissions
  • State changes: Notifying parent of internal state changes

Accessing Child Components

Using querySelector

this.template.querySelector('c-child-component').publicMethod();
<template>
    <c-clock lwc:ref="clockRef"></c-clock>
    <lightning-button onclick={handleRefresh}></lightning-button>
</template>
import { LightningElement } from 'lwc';

export default class Parent extends LightningElement {
    handleRefresh() {
        this.refs.clockRef.refresh();
    }
}

Error Handling

Always handle potential errors in public methods:
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class SafeComponent extends LightningElement {
    @api
    async performAction() {
        try {
            await this.riskyOperation();
        } catch (error) {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error',
                    message: error.message,
                    variant: 'error'
                })
            );
        }
    }
}

Build docs developers (and LLMs) love