Experience Site 45 min
Quick Deploy an Agent to an Experience Site
Outcome
A working chat widget on your Experience Site where visitors can message your Agentforce Service Agent in real-time.
When complete, you'll have:
- An Experience Cloud site with the Enhanced Chat component
- A Messaging Channel routed directly to your Service Agent
- Verified end-to-end message flow from widget to agent
This guide uses SF CLI commands as the primary method. REST API and browser fallbacks are included for each step.
Architecture
When a visitor opens the chat widget on your Experience Site, the message flows through a chain of Salesforce objects:
Click a node to jump to its configuration step.
The key routing link is SessionHandlerId on the MessagingChannel — it points directly to your agent's BotDefinition.Id. When a message arrives, Salesforce routes it to the handler specified by this ID.
Configure Your Variables
Update these variables with your values and they will be substituted in the code blocks below.
1. Verify Your Starting Point
Confirm your agent exists and your org is ready.
Confirm your Service Agent exists and is active
Before building the routing chain, verify your Agentforce Service Agent is deployed and active in the target org.
sf data query \
--target-org <your-org-alias> \
--query "SELECT Id, DeveloperName, MasterLabel, AgentType FROM BotDefinition WHERE DeveloperName='Reservation_Agent' AND IsActive=true"
Verify the agent is active:
Expected result: One record returned with a valid Id.
If no record is returned, activate your agent in Agent Builder before proceeding.
The agent must have AgentType = 'Bot' or AgentType = 'ServiceAgent'. Other agent types cannot be routed via Enhanced Chat.
Authenticate and verify org access
Ensure you have admin access to the target org and the CLI is connected.
sf org login web --alias <your-org-alias> --instance-url https://login.salesforce.com
sf org display --target-org <your-org-alias> --verbose
Verify org access:
Expected result: Org display shows your username and instance URL without errors.
2. Build the Routing Chain
Create the queue, channel, and deployment that route messages to your agent.
Create a messaging queue for fallback routing
The queue handles messages when the agent is unavailable. Even with direct agent routing, a fallback queue is required.
# Check if queue exists
sf data query --target-org <your-org-alias> \
--query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='AgentforceChannel_Queue'"
# If not found, create via Metadata API
cat > queue-metadata.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<Queue xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>AgentforceChannel_Queue</fullName>
<name>AgentforceChannel Queue</name>
<queueSobject>
<sobjectType>MessagingSession</sobjectType>
</queueSobject>
</Queue>
EOF
sf project deploy start --target-org <your-org-alias> --metadata Queue:AgentforceChannel_Queue
Verify queue exists:
Expected result: One queue record returned.
Create a Messaging Channel routed to your agent
The Messaging Channel is the key routing component. Setting SessionHandlerId to your agent's BotDefinition.Id enables direct routing.
# Get the Bot ID and Queue ID
BOT_ID=$(sf data query --target-org <your-org-alias> --json \
--query "SELECT Id FROM BotDefinition WHERE DeveloperName='Reservation_Agent'" \
| jq -r '.result.records[0].Id')
QUEUE_ID=$(sf data query --target-org <your-org-alias> --json \
--query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='AgentforceChannel_Queue'" \
| jq -r '.result.records[0].Id')
# Create or update MessagingChannel via Apex
sf apex run --target-org <your-org-alias> << EOF
MessagingChannel channel = new MessagingChannel();
channel.DeveloperName = 'AgentforceChannel';
channel.MasterLabel = 'AgentforceChannel';
channel.MessageType = 'EmbeddedMessaging';
channel.MessagingPlatformKey = 'AgentforceChannel-' + String.valueOf(Crypto.getRandomLong());
channel.IsActive = true;
channel.SessionHandlerId = '$BOT_ID';
channel.FallbackQueueId = '$QUEUE_ID';
insert channel;
System.debug('Created MessagingChannel: ' + channel.Id);
EOF
Verify channel configuration:
Expected result: One record with IsActive=true and SessionHandlerId matching your BotDefinition.Id.
If SessionHandlerId is not available in your org's API version, you'll need to configure routing through a Flow instead. See the Troubleshooting section.
Create an Embedded Service Deployment
The deployment packages the channel configuration and generates the code snippet for your site.
# Create EmbeddedServiceConfig via Tooling API
cat > esd-metadata.json << 'EOF'
{
"FullName": "AgentforceDeployment",
"Metadata": {
"masterLabel": "AgentforceDeployment",
"deploymentFeature": "EmbeddedMessaging",
"deploymentType": "Web",
"isEnabled": true,
"embeddedServiceMessagingChannel": {
"isEnabled": true,
"messagingChannel": "AgentforceChannel"
}
}
}
EOF
sf data create record --target-org <your-org-alias> --use-tooling-api \
--sobject EmbeddedServiceConfig --values "$(cat esd-metadata.json)"
Verify deployment exists:
Expected result: One deployment record returned.
3. Create the Experience Site
Stand up the site and add the chat widget component.
Create an Experience Cloud site
The Experience Site hosts your public-facing pages. We'll use the Customer Service template which includes Enhanced Chat support.
sf community create \
--target-org <your-org-alias> \
--name "AgentforceSite" \
--template-name "Customer Service" \
--url-path-prefix "mycompany"
Verify site exists:
Expected result: One site record returned.
Add the Enhanced Chat component to your site
The component renders the chat widget. It connects to your deployment configuration.
# Retrieve the site bundle
sf project retrieve start \
--target-org <your-org-alias> \
--metadata "DigitalExperienceBundle:site/AgentforceSite" \
--target-metadata-dir ./site-bundle
# The component must be added via Experience Builder (browser)
# See Browser method below
Verify component placement:
Expected result: The Enhanced Chat component appears in Experience Builder on the Home page.
Publish the Experience Site
Publishing makes the site accessible at its public URL.
sf community publish \
--target-org <your-org-alias> \
--name "AgentforceSite"
Verify site is published:
Expected result: Status = 'Live'.
4. Deploy & Verify
Test the full flow from widget to agent.
Get your site URL
Find the public URL where your chat widget is live.
sf org display --target-org <your-org-alias> --verbose --json | jq -r '.result.instanceUrl' | \
sed 's/\.my\.salesforce\./.my.site./'
# Append: /mycompany
Verify site URL:
Expected result: You have a URL like https://yourorg.my.site.com/{{DOMAIN_PREFIX}}.
Test the chat widget
Open your site and verify the widget appears and can send messages.
# Open the site in your browser
open "https://$(sf org display --target-org <your-org-alias> --json | jq -r '.result.instanceUrl' | sed 's/https:\/\///' | sed 's/\.my\.salesforce\./.my.site./').com/mycompany"
Verify chat functionality:
Expected result: Chat widget visible, message sends successfully, agent responds.
Verify message routing to agent
Confirm messages are being routed to your agent by checking MessagingSession and AgentWork records.
# Check recent MessagingSessions
sf data query --target-org <your-org-alias> \
--query "SELECT Id, Status, AgentType, OwnerId, CreatedDate FROM MessagingSession ORDER BY CreatedDate DESC LIMIT 5"
# Check AgentWork records
sf data query --target-org <your-org-alias> \
--query "SELECT Id, WorkItemId, BotId, RoutingType, CreatedDate FROM AgentWork ORDER BY CreatedDate DESC LIMIT 5"
Verify messaging session:
Expected result: Recent MessagingSession exists with Status = 'Active' or 'Ended'.
Troubleshooting
Widget doesn't appear on site
- Verify the Embedded Service Deployment is published
- Check that the Enhanced Chat component is on the Home page
- Republish the Experience Site after adding the component
- Clear browser cache and try incognito mode
Messages not reaching agent
- Verify
SessionHandlerIdis set on the MessagingChannel - Confirm the agent is Active (not Draft)
- Check that the Messaging Channel is Active
- Verify the fallback queue is properly configured
SessionHandlerId field not available
Some org configurations don't expose this field via API. Options:
- Configure routing via Omni-Channel Flow instead
- Use Setup UI to configure direct agent routing
- Contact Salesforce support for API access
Site publish fails
- Check for unpublished components or missing required fields
- Review the publish error in Setup → Digital Experiences
- Ensure you have admin permissions
Definition of Done
Definition of Done:
- Chat widget launcher visible on Experience Site
- User can open chat and send a message
- Agent responds to the message
- MessagingSession record created with correct routing
- AgentWork record shows message assigned to agent