Home / lwc / lwc-custom-lookup
lwc-custom-lookup
Custom lookup component in LWC — typeahead/autocomplete that searches records via Apex SOSL/SOQL, shows pills, supports keyboard navigation, and manages open/close state. Use when lightning-input-field or lightning-record-picker won't work (cross-org search, computed filters, custom result rendering). NOT for the base lightning-record-picker — use lwc/lwc-record-picker. NOT for in-form lookups inside lightning-record-edit-form.
Open the skill folder on GitHub
LWC Custom Lookup
The standard lightning-input-field (inside an LDS form) or lightning-record-picker (Spring '24+, free-standing) is the correct choice for ~90% of lookup use cases. Reach for a custom lookup only when those don't fit:
- Cross-org / external search — picking from a system other
than Salesforce (the Salesforce-side lookup needs a custom Apex method that talks to the external).
- Computed filters that change per-row — filter set depends
on other field values that the running user just changed; the declarative lookup filter cannot model.
- Multi-object search — one input that matches Accounts and
Contacts and Opportunities together (SOSL territory).
- Custom result rendering — second line, badges, conditional
icons; the standard picker shows one line.
The hard parts of a hand-rolled lookup are not the SOQL: they are debounce, keyboard accessibility, the open/close state machine, the pill UI, and not making the user search for the same thing they already selected. Skip any of those and the component feels broken even when it works.
Recommended Workflow
- Confirm
lightning-record-pickeris not enough. Spring '24added the standalone picker with
display-info,matching-info, andfilter. It supports cross-object search via theobjectApiNamearray. Read its docs first. - Design the Apex search. Use SOSL for multi-object,
short-string queries (
FIND :term IN ALL FIELDS RETURNING ...). Use SOQL withLIKEonly for single-object, indexed-field matches. Both withWITH USER_MODEand@AuraEnabled(cacheable=true).WITH USER_MODEis GA from API 57.0; the clause it replaces,WITH SECURITY_ENFORCED, no longer compiles at 67.0+ (Summer '26). - Debounce the search by 250-300ms. Use
setTimeout/clearTimeoutin the input'soninputhandler. Without debounce, every keystroke fires a callout — exhausting Apex CPU and pinning the org. - Build the open/close state machine. Three states: closed,
open-with-search-loading, open-with-results. Open on focus, close on blur (with a 200ms delay so result clicks land first), close on escape, close on selection.
- Implement keyboard navigation. Arrow up/down move
activeIndex, Enter selects, Escape closes. Renderaria-activedescendanton the input pointing at the result li so screen readers track focus. - Render the selected state as a pill. Once chosen, swap the
input for an SLDS pill (
<lightning-pill>) with a remove action. Re-clicking the remove returns to search mode. - Cache the SObject icon.
getObjectInfogives the icon URL;prepend it to results once per render rather than per result.
What This Skill Does Not Cover
- Lookups inside
lightning-record-edit-form— uselightning-input-fieldand configure lookup filters in metadata. lightning-record-picker(standalone, Spring '24+) — seelwc/lwc-record-picker.- Lookup filters at the field-metadata level — see
admin/lookup-filter-design. - Type-ahead against external systems — see
integration/external-search-via-named-credential.