salesforce

Lightning Record Edit Form: Salesforce Guide

Building inline editing experiences in Salesforce doesn't require complex Aura components or messy custom controller logic anymore. You can build fast, secure, and native feeling forms using standard

Lightning Record Edit Form: Salesforce Guide
In this story

Building inline editing experiences in Salesforce doesn't require complex Aura components or messy custom controller logic anymore. You can build fast, secure, and native-feeling forms using standard Lightning Web Components. If you're tired of writing boilerplate just to let users update an Account name or Close Date right from a record page, this tool solves that exact problem.

The lightning-record-edit-form component is a built-in wrapper that handles field-level security, object-level permissions, and data validation automatically. It connects directly to Salesforce data without requiring Apex controllers for standard CRUD operations. When you use it correctly, you get automatic formatting based on field types—like picklists, currencies, and dates—straight out of the box.

Understanding how to wire this component, handle submit events, and display field errors properly will save you hours of debugging. Let's look at how to set it up, avoid common pitfalls, and extend it for dynamic layouts.

Understanding Lightning Record Edit Form

At its core, the lightning-record-edit-form provides a container that knows how to load, edit, and save Salesforce records using standard Lightning data services. Unlike standard apex-backed forms, this approach respects user permissions automatically. If a user doesn't have read access to a field, it won't show up. If they lack edit permissions, the form locks it down.

Core Components and Architecture

To build a complete editing interface, you pair the edit form with specific child elements.

  • lightning-input-field: Renders the input control for a specific field based on its metadata.
  • lightning-messages: Displays validation errors and server-side save errors at the top of the container.
  • lightning-button: Triggers the submission of the form.

When a user interacts with these elements, the Salesforce platform handles caching and LDS (Lightning Data Service) record notification refreshes under the hood. You don't have to manually query the database or write SOQL queries just to update a text field.

When to Use Edit Form vs. Record Form

Salesforce offers multiple ways to handle records in UI components. Knowing when to pick the edit form over alternatives prevents architectural rework later.

Use lightning-record-form when you want a quick, zero-configuration layout that renders standard view, edit, or create modes automatically. It's great for simple use cases where you don't need custom styling or complex event handling.

Use lightning-record-edit-form when you need fine-grained control over the layout, custom button placements, conditional field rendering, or specific JavaScript logic triggered during the submit lifecycle. It gives you the canvas layout you need while keeping data operations native.

Building Your First Dynamic In-Place Form

Let's walk through creating a reusable component that lets users update Contact details inline without navigating away from the parent account page.

Step 1: The HTML Template

Your HTML structure needs to reference the target object API name and map individual fields using input components.

<template>
    <lightning-card title="Edit Contact Details" icon-name="standard:contact">
        <div class="slds-m-around_medium">
            <lightning-record-edit-form
                record-id={recordId}
                object-api-name="Contact"
                onsuccess={handleSuccess}
                onerror={handleError}>
                
                <lightning-messages></lightning-messages>
                
                <lightning-input-field field-name="FirstName"></lightning-input-field>
                <lightning-input-field field-name="LastName"></lightning-input-field>
                <lightning-input-field field-name="Email"></lightning-input-field>
                <lightning-input-field field-name="Phone"></lightning-input-field>
                
                <div class="slds-m-top_medium">
                    <lightning-button
                        class="slds-m-right_x-small"
                        type="submit"
                        label="Save"
                        variant="brand">
                    </lightning-button>
                    <lightning-button
                        label="Cancel"
                        onclick={handleCancel}>
                    </lightning-button>
                </div>
            </lightning-record-edit-form>
        </div>
    </lightning-card>
</template>

Step 2: The JavaScript Controller

Your JavaScript file handles the component properties, navigation events, and success toasts.

import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

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

    handleSuccess(event) {
        const evt = new ShowToastEvent({
            title: 'Success!',
            message: 'Record updated successfully.',
            variant: 'success',
        });
        this.dispatchEvent(evt);
    }

    handleError(event) {
        const evt = new ShowToastEvent({
            title: 'Error updating record',
            message: event.detail.message,
            variant: 'error',
        });
        this.dispatchEvent(evt);
    }

    handleCancel() {
        // Reset form or navigate away if needed
        const inputFields = this.template.querySelectorAll('lightning-input-field');
        if (inputFields) {
            inputFields.forEach(field => {
                field.reset();
            });
        }
    }
}

Step 3: Configuring the Metadata XML

Make sure your component is exposed to record pages by configuring the target settings properly.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>59.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage">
            <objects>
                <object>Account</object>
            </objects>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

For official documentation on component configuration properties, check the Salesforce Lightning Web Components Developer Guide.

Handling Form Submission and Data Manipulation

By default, clicking a button with type="submit" inside the form triggers the standard save action. But what happens if you need to modify field values programmatically before they hit the database?

You can intercept the submit event using the onsubmit attribute in your HTML.

<lightning-record-edit-form
    record-id={recordId}
    object-api-name="Case"
    onsubmit={handleSubmit}>

In your JavaScript, you catch the event, prevent the default submission temporarily if needed, manipulate the fields object, and submit programmatically:

handleSubmit(event) {
    event.preventDefault(); // Stop default form submit
    const fields = event.detail.fields;
    
    // Example: Automatically append text to description
    fields.Description = fields.Description + '\nUpdated via custom LWC interface.';
    
    // Submit the mutated fields
    this.template.querySelector('lightning-record-edit-form').submit(fields);
}

This pattern gives you complete control over data hygiene without writing Apex triggers for simple UI-driven rules.

Common Pitfalls and How to Fix Them

Even experienced developers run into subtle issues when building inline editing forms. Knowing these traps ahead of time saves hours of frustration.

Missing Record IDs in Create Mode

If you use the edit form without supplying a record-id, it operates in create mode. If you accidentally pass an empty string or undefined variable from a parent component, the form fails silently or throws confusing LDS errors. Always ensure your conditional rendering checks whether a record ID exists before rendering the form if you intend to update an existing record.

Layout Refresh Issues

When a record updates successfully, the local Lightning Data Service cache updates, but dependent components on the same page might not refresh automatically. To fix this, import updateRecord from lightning/uiRecordApi or use the standard refresh mechanism.

You can also read up on data caching best practices via the Salesforce Architecture Blog.

Field-Level Security Confusion

Developers often wonder why a specific field isn't rendering inside an input component. If the running user's profile lacks field-level read permissions, the form drops the field entirely rather than throwing an error. Always verify object and field permissions in your scratch org or sandbox before assuming your markup is broken.

Frequently Asked Questions

Can I use lightning-record-edit-form for custom objects?

Yes. It works seamlessly with both standard and custom objects. Just ensure your object API names include the standard __c suffix where applicable, such as Project__c.

How do I clear form fields after a successful save?

You can iterate through all child lightning-input-field elements in your JavaScript controller and call their built-in .reset() method, or use standard reactive property bindings.

Why are picklist values not showing up?

Picklist values load dynamically based on the object metadata and record type context. If no record type is specified and multiple exist, Salesforce uses the default record type for that user profile.

Can I pre-populate fields when creating a new record?

Yes. When operating in create mode (omitting the record-id attribute), you can pass default values directly into the lightning-input-field elements using standard value bindings or by mutating fields during the submit handler.

CR

Written by

Chloe Ramirez

Chloe Ramirez excels at making complicated information accessible, turning dense research into clear narratives that engage diverse audiences.

More from salesforce