<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
}
}
}
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>
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.
<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!