A Service Console utility that lets agents capture case details fast, built from a Lightning Web Component (LWC) wrapped in a small Aura component. Below is the architecture, the Aura, LWC and Apex code, and how I handle errors and slow record loads.
Overview
Call center agents need to capture case details while the caller is still on the line. This post builds a utility action for the Salesforce Service Console that opens a standalone LWC, captures the case information, links it to a Contact record when one is available, and copes with invalid contexts and slow loads.
Use case
Where this comes up:
- Dual-monitor setups where the utility is used on a secondary screen.
- Agents searching for contacts by PII (SSN, DOB, Name) while on calls.
- Contact records that may load slowly due to backend latency.
- Case details that have to be captured immediately and linked once the contact is available.
Solution architecture
Three parts:
- An Aura component wrapping the LWC, so recordId reaches it reliably.
- The Lightning Web Component itself, which provides the UI for capturing case details and calls Apex to insert the Case.
- An Apex controller that inserts the Case record securely from the LWC.
Why use Aura as a wrapper?
An LWC launched from certain console contexts does not reliably receive the recordId. Wrapping it in a lightweight Aura component (using force:hasRecordId) makes the recordId available every time and passes it into the LWC.
Key features
- Open the utility in a separate window so agents can multitask.
- Search contacts by PII while continuing to type case details.
- Link the case to a Contact when the record is loaded; prevent saves if context is invalid.
- Minimize the utility programmatically to clear the screen without losing what the agent typed.
Best practices
- Validate the recordId prefix (e.g., '003' for Contact) before attempting to set the ContactId on the Case.
- Keep the Aura wrapper minimal. It should only capture recordId and pass it to the LWC.
- Use optimistic UI where possible: let agents enter case details while contact data is still loading.
- Handle Apex errors cleanly and show actionable toast messages to users.
Code snippets
Aura wrapper (markup)
<aura:component implements="force:hasRecordId,flexipage:availableForAllPageTypes,lightning:utilityItem"> <aura:attribute name="recordId" type="String" /> <aura:handler name="init" value="{!this}" action="{!c.doInit}" /> <c:createCaseUtility contactId="{!v.recordId}"/>
Aura controller (client-side JS)
({ doInit: function (component, event, helper) { var recordId = component.get("v.recordId"); if (!recordId) { console.warn("Record ID is undefined. Ensure the utility is launched from a record context."); } else { console.log("Record ID retrieved:", recordId); } } });
LWC template (HTML)
LWC JavaScript (controller)
import { LightningElement, wire, api } from 'lwc'; import createCase from '@salesforce/apex/CreateCaseController.createCase'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; import { minimize, EnclosingUtilityId } from 'lightning/platformUtilityBarApi'; import { getRecord } from 'lightning/uiRecordApi'; const CONTACT_FIELDS = ['Contact.Name','Contact.Phone','Contact.AccountId'];
export default class CreateCaseUtility extends LightningElement { contactName; contactPhone; accountId; caseOrigin; caseType; description; caseReason; caseStatus; subject;
@wire(EnclosingUtilityId) utilityId;
currentRecordId;
@api
set contactId(value) {
if (value !== this.currentRecordId) {
this.currentRecordId = value;
}
}
get contactId() {
return this.currentRecordId;
}
@wire(getRecord, { recordId: '$currentRecordId', fields: CONTACT\_FIELDS })
wiredCase({ error, data }) {
if (data) {
this.contactName = data.fields.Name.value;
this.contactPhone = data.fields.Phone.value;
this.accountId = data.fields.AccountId.value;
} else if (error) {
console.error('Error fetching Contact:', error);
}
}
handleInputChange(event) { /\* ... \*/ }
resetForm() { /\* ... \*/ }
async handleMinimize() { /\* ... \*/ }
showToast(title, message, variant) { /\* ... \*/ }
validateCaseId() { /\* ... \*/ }
handleSave() { /\* ... \*/ }
}
Apex controller
public class CreateCaseController { @AuraEnabled public static void createCase(Case cse) { insert cse; } }
How to add as a utility
Deploy the Aura and LWC bundles, then add the Aura component to the Service Console utility bar. Configure the utility to allow opening in a separate window to enable the dual-monitor workflow.
Conclusion
A minimal Aura wrapper plus an LWC utility gives call center agents a way to capture case details without losing context. Inputs survive while the contact record loads, which is where most of the accuracy problem was.
For admins, developers and the business, it is a low-risk change to the agent workflow that reduces AHT (average handle time) and improves case quality.
Leave a Comment