In short
- Start with what the rep needs to do on the record page, then design the widget around that one job.
- Keep API calls in Apex, with endpoints and keys in named credentials and settings in Custom Metadata.
- Validate required fields in the widget, and refresh when a field is saved, with no page reload.
- Show a loading state, show clear errors, and log every failure in Salesforce.
The example: a HiLite widget in Salesforce
HiLite is a financial platform. Reps needed to send a lead or opportunity to HiLite from Salesforce, and then open the same record in HiLite. We built a Lightning Web Component on the record page with two buttons: Send to HiLite and Open in HiLite.
Around those buttons the widget checks the fields HiLite needs, shows what is missing, and syncs changes after the first send. The steps below work for any widget.
1. Plan the Salesforce LWC widget
- The job: what does the rep click, and what should happen?
- The data: which fields does the widget read, and which does the other system need?
- The rules: what blocks a send, and what message does the rep see?
- The settings: what changes per location or team? Those go in Custom Metadata, not code.
2. Create the component bundle
HTML template
The card, buttons, field checklist, loading spinner and error area. Use Lightning base components so the widget looks like Salesforce.
JavaScript
Declare @api recordId so the page passes the record. Use @wire(getRecord) to read the fields. Handle the button clicks.
Meta file
Set isExposed to true and add lightning__RecordPage as a target, limited to the objects the widget belongs on.
3. Write the Apex controller
- An @AuraEnabled method builds the payload from the record and calls the external API.
- The endpoint and credentials sit in a named credential. Facility or account IDs sit in Custom Metadata.
- The method saves the external ID back on the record, so the next click opens the right record.
- Errors are caught, logged to a custom error object, and returned to the widget as a plain message.
Talk through your project
A free call about your integration, your CRM or whatever you are stuck on. Honest advice, even if you never hire us. No obligation.
4. Validate fields and refresh on save
Show the fields the other system needs, with a check or a warning next to each. When the rep fixes a field and saves, the widget should update on its own. The wired getRecord call refreshes when the record changes, so the checklist re-runs with no page refresh.
5. Loading states, buttons and banners
- Show a spinner while the API call runs, and disable the button so it is not clicked twice.
- Show a success toast with the result, and an error toast with the reason.
- Swap Send for Open once the record exists in the other system.
- For status, a banner widget works well: a green banner when a stage is reached, a red one for a do-not-call flag.
6. Keep the systems in sync after the first send
After the first send, changes to key fields should follow. An Apex trigger or flow watches those fields and sends the update. If a change needs a fresh send, like a new facility, detect it and re-send. Log each sync failure, so an admin can see it and fix it.
7. Test, deploy and add to the page
Build in a sandbox, write Apex tests for the controller with a mocked callout, and deploy with your normal release process. Then add the widget to the record pages in Lightning App Builder and test with each profile that will use it.
Want help with this?
Book a free call about your CRM, integrations or reporting, or map your systems first with our free tech stack diagram builder.
