Skip to main content

LWC Custom Search in Salesforce - Full Code

Salesforce Lightning Web Components (LWC) provide a modern, high-performance web framework for building responsive user interfaces on the Salesforce platform. In this guide, we will step through creating a real-time, dynamic record search component using LWC and Apex.

In plain words: A custom LWC search component lets users type into an input field and instantly filter Salesforce records (like Accounts or Contacts) without reloading the page.

Prerequisites

Before writing the component code, ensure your environment is configured with the following requirements:

  • Salesforce Developer Org: A active developer sandbox or scratch org.
  • Salesforce CLI: Installed on your local machine for deployments.
  • IDE: Visual Studio Code with the Salesforce Extension Pack installed.

Step-by-Step Implementation

Implementation Flow: We will construct a three-tier architecture: an HTML template for UI presentation, a JavaScript file for reactive wired data handling, and a backend Apex class to perform SOQL queries.

Step 1: Create a New Lightning Web Component

Open your terminal in VS Code and run the following Salesforce CLI command to generate a new component named CustomSearch:

sf project generate component -n CustomSearch -d force-app/main/default/lwc --type lwc

Step 2: Edit the HTML Markup

Open CustomSearch.html and replace its contents with the following markup:

<template>
    <lightning-card title="Custom Search" icon-name="standard:search">
        <div class="slds-m-around_medium">
            <lightning-input 
                type="search" 
                label="Enter search keyword" 
                onchange={handleSearchTermChange}>
            </lightning-input>
        </div>

        <div class="slds-m-around_medium">
            <template if:true={searchResults}>
                <ul class="slds-list_dotted">
                    <template for:each={searchResults} for:item="result">
                        <li key={result.Id}>{result.Name}</li>
                    </template>
                </ul>
            </template>

            <template if:false={searchResults}>
                <p>No results found.</p>
            </template>
        </div>
    </lightning-card>
</template>

Step 3: Edit the JavaScript Controller

Open CustomSearch.js and configure the reactive properties and wire service callout:

import { LightningElement, track, wire } from 'lwc';
import searchRecords from '@salesforce/apex/CustomSearchController.searchRecords';

export default class CustomSearch extends LightningElement {
    @track searchTerm = '';
    @track searchResults;

    handleSearchTermChange(event) {
        this.searchTerm = event.target.value;
    }

    @wire(searchRecords, { searchTerm: '$searchTerm' })
    wiredSearchResult({ error, data }) {
        if (data) {
            this.searchResults = data;
        } else if (error) {
            console.error('Error retrieving search results:', error);
        }
    }
}
Common Developer Mistake: Omitting the $ prefix when passing reactive variables to wire services (e.g., '$searchTerm') prevents the wire service from automatically re-evaluating when the input value updates.

Step 4: Create the Apex Controller Class

Create an Apex class named CustomSearchController.cls to handle the backend database query:

public with sharing class CustomSearchController {
    @AuraEnabled(cacheable=true)
    public static List<Account> searchRecords(String searchTerm) {
        if (String.isBlank(searchTerm)) {
            return new List<Account>();
        }
        String searchKey = '%' + searchTerm + '%';
        return [SELECT Id, Name FROM Account WHERE Name LIKE :searchKey LIMIT 10];
    }
}
Always include cacheable=true on @AuraEnabled Apex methods called via LWC wire adapters to optimize client-side performance and reduce unnecessary server requests.

Step 5: Deploy the Code to Your Salesforce Org

Deploy the component and class source files using the CLI:

sf project deploy start --source-dir force-app

Step 6: Add Component to Lightning App Builder

  • Navigate to Setup > User Interface > Lightning App Builder.
  • Select an existing Account Record Page or create a new App Page.
  • Locate CustomSearch under custom components and drag it onto the canvas.
  • Save and activate the page.
Component Architecture Summary
  • UI Layer: Native Lightning Design System (SLDS) tags with dynamic iteration.
  • Controller: Reactive wire adapter bound to state variables via '$searchTerm'.
  • Backend: with sharing enforcement with cached SOQL query filters.

Conclusion

Building custom search capabilities with Lightning Web Components yields responsive, scalable solutions on Salesforce. By leveraging LWC wire services alongside cacheable Apex endpoints, developers maintain optimal client performance while retrieving data dynamically.