Skip to main content

How to Embed and Run Salesforce Flows Inside Lightning Web Components (LWC)

In plain words: Salesforce Flows are powerful automated workflows, while Lightning Web Components (LWC) provide custom user interfaces. You don't have to choose between them—Salesforce provides a built-in base component called <lightning-flow> that allows you to embed and run a fully interactive Screen Flow directly inside your custom LWC interface.

Salesforce Flows allow admins to build complex business logic and guided user screens without writing code. However, when you need a custom UI layout or want to trigger a flow conditionally based on advanced user actions, embedding the flow inside a Lightning Web Component (LWC) is the ideal solution.

In this guide, we will explore how to use the native lightning-flow tag to launch a Screen Flow on demand from an LWC.

Step 1: Create the LWC Component

Open your terminal and use the Salesforce CLI to generate your component files:

sf lightning generate component -n addLightningFlow -d force-app/main/default/lwc

Step 2: Build the HTML Template

Open addLightningFlow.html. We will include a button to let the user start the flow, and wrap the <lightning-flow> tag in a conditional block so it only renders when clicked.

<template>
    <lightning-card title="Embedded Flow Runner" icon-name="utility:flow">
        <div class="slds-m-around_medium">
            
            <!-- Button to trigger the flow -->
            <template lwc:if={flowNotStarted}>
                <lightning-button 
                    label="Start Guided Flow" 
                    onclick={handleStartFlow} 
                    variant="brand">
                </lightning-button>
            </template>

            <!-- The Native Lightning Flow Component -->
            <template lwc:if={flowStarted}>
                <lightning-flow
                    flow-api-name="Your_Active_Flow_Api_Name"
                    onstatuschange={handleFlowStatusChange}>
                </lightning-flow>
            </template>

        </div>
    </lightning-card>
</template>

Step 3: Write the JavaScript Controller

Open addLightningFlow.js. We will handle the button click event to switch the visibility state, and listen for when the flow finishes running.

import { LightningElement, track } from 'lwc';

export default class AddLightningFlow extends LightningElement {
    @track flowStarted = false;

    get flowNotStarted() {
        return !this.flowStarted;
    }

    handleStartFlow() {
        this.flowStarted = true;
    }

    // Handles events when the flow finishes or encounters an error
    handleFlowStatusChange(event) {
        if (event.detail.status === 'FINISHED') {
            console.log('Flow completed successfully!');
            // You can add logic here to redirect or refresh the page
            this.flowStarted = false; // Reset the flow
        }
    }
}
Developer Trap: Using Inactive Flows
The flow-api-name attribute requires the exact API name of a flow that has been activated in your Salesforce Setup. If you pass the API name of a flow that is still saved as a draft or deactivated, the component will fail to render and throw a generic error in the console.

Step 4: Passing Input Variables to the Flow

Often, your LWC sits on a record page (like an Account) and you need to pass the current record ID into your flow so it knows which record to update. You can achieve this easily by passing an array of input variables to the <lightning-flow> element.

JavaScript modification for inputs:

import { LightningElement, api, track } from 'lwc';

export default class AddLightningFlow extends LightningElement {
    @api recordId; // Automatically populated if placed on a record page
    @track flowStarted = false;

    get inputVariables() {
        return [
            {
                name: 'recordId', // Must match the variable name inside your Flow!
                type: 'String',
                value: this.recordId
            }
        ];
    }
}

Then update your HTML tag to bind those variables: <lightning-flow flow-api-name="Your_Flow_Name" input-variables={inputVariables}></lightning-flow>

360 Card: lightning-flow Attributes
  • flow-api-name: The unique developer name of the active Screen Flow.
  • input-variables: An array passing parameters from LWC into flow variables.
  • onstatuschange: An event listener that fires whenever the flow changes screens or finishes execution.
Core Takeaway: You can seamlessly embed Salesforce Screen Flows inside custom LWC interfaces using the native <lightning-flow> base component and pass record IDs using input variables.

Conclusion

Embedding Salesforce Flows inside Lightning Web Components gives you the ultimate hybrid development model—combining the point-and-click power of declarative flows with the responsive, custom UI flexibility of LWC. By utilizing lightning-flow and handling status events in JavaScript, you can streamline complex business processes right from your users' custom screens.

Happy coding!