1. Setup Routing Configuration.

2. Create a Queue.

3. Create a Chat Button with the Queue created in Step 2.

4. Create a Chat Deployment.

5. Create Embedded Service Deployment.

6. Enable “Digital Experiences ” by navigating to Settings under Digital Experiences section in Setup.
7. Create a simple Site(Community). I used Partner Central template for this implementation.
8. Create a Channel Menu.

9. Set up menus for the Channel Menu.

10. Add the Channel Menu to the Experience Site.

11. Allow the Embedded Service Chat endpoints in the Experience Builder.

12. Create the below LWC for custom Pre-Chat.
HTML:
<template>
<template if:true={backgroundImgURL}>
<img src={backgroundImgURL}/>
</template>
<lightning-card title="Prechat Form">
<template class="slds-m-around_medium" for:each={fields} for:item="field">
<div key={field.name}>
<lightning-input
key={field.name}
name={field.name}
label={field.label}
value={field.value}
max-length={field.maxLength}
required={field.required}>
</lightning-input>
</div>
</template>
</lightning-card>
<lightning-button
label="Start Chat"
title="Start Chat"
onclick={handleStartChat}
class="slds-m-left_x-small"
variant="brand">
</lightning-button>
</template>
JavaScript:
import BasePrechat from 'lightningsnapin/basePrechat';
import { api, wire } from 'lwc';
const FIELDS = [ 'User.FirstName', 'User.LastName', 'User.Email', 'User.Phone' ];
import Id from '@salesforce/user/Id';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { getRecord } from 'lightning/uiRecordApi';
export default class PreChatLwc extends BasePrechat {
@api prechatFields;
@api backgroundImgURL;
fields;
namelist;
objUser;
error;
userId = Id;
@wire( getRecord, { recordId: '$userId', fields: FIELDS } )
wiredRecord({ error, data }) {
if ( error ) {
let message = 'Unknown Error';
if ( Array.isArray( error.body ) )
message = error.body.map(e => e.message).join( ', ' );
else if ( typeof error.body.message === 'string' )
message = error.body.message;
this.dispatchEvent(
new ShowToastEvent( {
title: 'Error fetching User details',
message,
variant: 'error',
} )
);
} else if ( data ) {
console.log( 'User ' + JSON.stringify( data ) );
this.objUser = data.fields;
this.fields = this.fields.map( field => {
console.log( 'Field is ' + JSON.stringify( field ) );
if ( field.name === 'FirstName' )
field.value = this.objUser.FirstName.value;
else if ( field.name === 'LastName' )
field.value = this.objUser.LastName.value;
else if ( field.name === 'Email' )
field.value = this.objUser.Email.value;
else if ( field.name === 'Phone' )
field.value = this.objUser.Phone.value;
console.log( 'Field after passing value is ' + JSON.stringify( field ) );
return field;
});
}
}
connectedCallback() {
this.fields = this.prechatFields.map( field => {
const { label, name, value, required, maxLength } = field;
return { label, name, value, required, maxLength };
});
this.namelist = this.fields.map( field => field.name );
console.log( 'Name list is ' + this.namelist );
}
/*
Focus on the first input after this component renders.
*/
renderedCallback() {
this.template.querySelector("lightning-input").focus();
}
/*
On clicking the 'Start Chatting' button, send a chat request.
*/
handleStartChat() {
this.template.querySelectorAll( "lightning-input" ).forEach( input => {
this.fields[ this.namelist.indexOf( input.name ) ].value = input.value;
});
if ( this.validateFields( this.fields ).valid ) {
let isValid = true;
for ( let field of this.fields ) {
if ( field.required && !field.value ) {
isValid = false;
break;
}
}
if( isValid )
this.startChat(this.fields);
} else {
this.dispatchEvent(
new ShowToastEvent( {
title: 'An Error occured',
message: 'Error while initiating the Chat. Reach out to us via Phone',
variant: 'error',
} )
);
}
}
}
CSS:
:host {
display: flex;
flex-direction: column;
}
lightning-button {
padding-top: 1em;
}
js-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>50.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightningSnapin__PreChat</target>
</targets>
</LightningComponentBundle>
13. Configure the LWC in the Embedded Service Deployment.

14. Initiate a Chat from Salesforce Digital Experience Site.

15. The pre-chat form will be auto populated based on the logged in user information.
