Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ After installing the package, complete these steps to wire everything together.

The package includes a pre-configured Agentforce agent (`haaHelpAgent`) that answers customer questions using knowledge articles. Follow the instructions below to configure it.

> **Note:** Complete your Data Cloud setup ahead of time so you're ready to hit the ground running.
> **Note:** Complete your Data Cloud setup ahead of time so you're ready to hit the ground running.
> **Important:** The Help Agent requires Knowledge articles to function. You must create Knowledge articles in your org with appropriate content fields before setting up the agent. The agent searches these articles to answer questions.

#### Prerequisites
Expand Down Expand Up @@ -318,7 +318,7 @@ EnhancedChatInline.init({
All UI text is externalized as Salesforce custom labels prefixed with `HAA_`. Edit them in **Setup → Custom Labels**:

- **Heading, placeholder, button text** — `HAA_heading`, `HAA_input_placeholder`, `HAA_submit_altText`, etc.
- **Error messages** — `HAA_error_timeout`, `HAA_error_scriptLoadFailed`, `HAA_error_launchFailed`, etc.
- **Error messages** — `HAA_error_timeout`, `HAA_error_scriptLoadFailed`, `HAA_error_launchFailed`, `HAA_error_previewEnvironment` (shown in Experience Builder and preview environments only), etc.
- **Canned prompts** — `HAA_canned_prompt_one`, `HAA_canned_prompt_two`, `HAA_canned_prompt_three`. Set any label value to `skip` to hide that button.

### Styling
Expand All @@ -329,6 +329,14 @@ The component inherits colors and fonts from your site theme automatically via S

## Troubleshooting

### Component shows an error in Experience Builder or preview

This is expected behaviour. The component displays an informational message — _"Chat is not available in the Experience Builder or preview environments. To test this component, publish the site and visit the published URL."_ — in all Experience Builder and preview environments. No "Try again" button is shown because retrying will not help.

This is a Salesforce platform limitation: the Embedded Service bootstrap script and the SCRT configuration API are both served from the published site's domain (`*.my.site.com`), and Salesforce's own CORS and CSP policies block requests originating from the preview domains (`*.salesforce-experience.com`). There is no workaround at the component level.

To test the component, publish your Experience Cloud site and visit the published URL.

- **Chat not loading** — Verify Org ID, Deployment API Name, and Site URL match the Code Snippet exactly. Check that the deployment is published and the messaging channel is active.
- **Timeout error** — Enable debug logs and check the browser console for which lifecycle event didn't fire. Common causes: deployment not published, site URL mismatch, or messaging channel not activated.
- **CORS / frame-ancestors errors** (third-party embed) — Add your hosting domain to the deployment's Trusted Domains in Setup.
Expand Down
8 changes: 8 additions & 0 deletions force-app/main/default/labels/CustomLabels.labels-meta.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@
<shortDescription>Inline Help error no chat container</shortDescription>
<value>Chat container not found.</value>
</labels>
<labels>
<fullName>HAA_error_previewEnvironment</fullName>
<categories>HAA</categories>
<language>en_US</language>
<protected>false</protected>
<shortDescription>Inline Help error preview environment</shortDescription>
<value>Chat is not available in the Experience Builder or preview environments. To test this component, publish the site and visit the published URL.</value>
</labels>
<labels>
<fullName>HAA_error_scriptLoadFailed</fullName>
<categories>HAA</categories>
Expand Down
18 changes: 6 additions & 12 deletions force-app/main/default/lwc/haaInlineEnhancedChat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The component is a Salesforce LWC (Lightning Web Component) that embeds Agentfor
| LAUNCHING | Skeleton loader | `utilAPI.launchChat()` called, waiting for `ConversationOpened` event |
| SENDING | Skeleton loader | Conversation opened, waiting for `FirstBotMessageSent`, then `sendTextMessage()` |
| ACTIVE | Chat iframe (crossfade from skeleton) | Message sent, iframe polled and revealed, timers cleared |
| ERROR | Error message + "Try again" | Failure occurred (timeout, init error, API rejection) |
| ERROR | Error message + "Try again" (hidden for preview errors) | Failure occurred (timeout, init error, API rejection, or preview environment detected) |

### Transition Table

Expand Down Expand Up @@ -146,7 +146,8 @@ When the page reloads with an existing session in localStorage:
| `HAA_submit_altText` | Submit button alt text |
| `HAA_loading_altText` | Loading spinner alt text |
| `HAA_retry_label` | Retry button label |
| `HAA_error_*` | Error messages (7 variants) |
| `HAA_error_*` | Error messages (8 variants) |
| `HAA_error_previewEnvironment` | Only shown in Experience Builder and preview environments where chat fails to load |
| `HAA_canned_prompt_one/two/three` | Canned prompt button labels (set to `skip` to hide) |

## Child Components
Expand Down Expand Up @@ -177,15 +178,8 @@ Used on **window close** (`onEmbeddedMessagingWindowClosed` → `CONV_CLOSED`).

Used only in **`disconnectedCallback`** when the component is destroyed. Removes event listeners, global DOM injected by the bootstrap outside the shadow DOM (FAB, overlays, iframes, styles via broad `querySelectorAll`), and resets all internal flags. This is not used on conversation close because the aggressive global DOM removal breaks recovery under Lightning Web Security (LWS), and LWS cannot be reliably detected at runtime.

## Known Issues
## Experience Builder and Preview Environments

### Experience Builder Preview CORS Error
The component detects all Salesforce Experience Cloud builder and preview domains (`*.builder.salesforce-experience.com`, `*.preview.salesforce-experience.com`, `*.live-preview.salesforce-experience.com`, etc.) and immediately shows the `HAA_error_previewEnvironment` label message without attempting to load the bootstrap. This is intentional — the Embedded Service bootstrap and SCRT configuration API are served from the published site domain (`*.my.site.com`) and Salesforce's own CORS and CSP policies block requests from preview origins. The "Try again" button is hidden in this state since retrying will not help.

The Experience Builder preview domain (`*.live-preview.salesforce-experience.com`) is a different origin from the actual site (`*.my.site.com`). This causes CORS errors when the component tries to load `bootstrap.min.js`:

```
Access to fetch at '...bootstrap.min.js' from origin '...live-preview.salesforce-experience.com'
has been blocked by CORS policy
```

**Workaround:** Publish the site and test on the actual `*.my.site.com` domain. The preview environment does not fully support cross-origin embedded messaging.
To test the component, publish the site and visit the published URL.
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ <h1 class="loading-heading">{labels.HAA_heading}</h1>
<template lwc:if={isError}>
<div class="chat-error slds-text-color_error">
<p>{errorMessage}</p>
<lightning-button variant="base" label={labels.HAA_retry_label} onclick={handleRetry}
class="slds-m-top_small"></lightning-button>
<template lwc:if={showRetryButton}>
<lightning-button variant="base" label={labels.HAA_retry_label} onclick={handleRetry}
class="slds-m-top_small"></lightning-button>
</template>
</div>
</template>
<div lwc:ref="chatContainer" class="chat-container"></div>
</div>
</div>
</template>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import HAA_error_timeout from "@salesforce/label/c.HAA_error_timeout";
import HAA_canned_prompt_one from "@salesforce/label/c.HAA_canned_prompt_one";
import HAA_canned_prompt_two from "@salesforce/label/c.HAA_canned_prompt_two";
import HAA_canned_prompt_three from "@salesforce/label/c.HAA_canned_prompt_three";
import HAA_error_previewEnvironment from "@salesforce/label/c.HAA_error_previewEnvironment";

// --- States ---
const STATE = Object.freeze({
Expand Down Expand Up @@ -106,7 +107,7 @@ const IFRAME_POLL_MS = 120;
const IFRAME_MAX_WAIT_MS = 6000;
const DEFAULT_CHAT_HEIGHT = "550px";
const MIN_CHAT_HEIGHT_PX = 400;
const VERSION = "v1.03";
const VERSION = "v1.04";

export default class HaaInlineEnhancedChat extends LightningElement {
@api orgId;
Expand Down Expand Up @@ -135,6 +136,7 @@ export default class HaaInlineEnhancedChat extends LightningElement {
_launchFallbackId = null;
_sendFallbackId = null;
_chatRevealed = false;
_isPreviewError = false;
_boundListeners = {};

// --- Computed properties ---
Expand Down Expand Up @@ -162,6 +164,10 @@ export default class HaaInlineEnhancedChat extends LightningElement {
return this._state === STATE.ERROR;
}

get showRetryButton() {
return !this._isPreviewError;
}

_isMultiline = false;

get inputRowClass() {
Expand Down Expand Up @@ -222,7 +228,8 @@ export default class HaaInlineEnhancedChat extends LightningElement {
HAA_error_timeout,
HAA_canned_prompt_one,
HAA_canned_prompt_two,
HAA_canned_prompt_three
HAA_canned_prompt_three,
HAA_error_previewEnvironment
};

get _isCannedPromptsEnabled() {
Expand Down Expand Up @@ -277,6 +284,11 @@ export default class HaaInlineEnhancedChat extends LightningElement {

connectedCallback() {
this._debug("version", VERSION);
if (this._isSitePreview()) {
this._isPreviewError = true;
this._dispatch(EVT.INIT_ERROR, { message: this.labels.HAA_error_previewEnvironment });
return;
}
if (this._hasValidConfig()) {
this._loadBootstrapScript();
}
Expand Down Expand Up @@ -388,6 +400,7 @@ export default class HaaInlineEnhancedChat extends LightningElement {
this._pendingQuery = "";
this.errorMessage = "";
this._chatRevealed = false;
this._isPreviewError = false;
break;

default:
Expand Down Expand Up @@ -476,6 +489,12 @@ export default class HaaInlineEnhancedChat extends LightningElement {
const query = (this.searchQuery || "").trim();
if (!query) return;

if (this._isSitePreview()) {
this._isPreviewError = true;
this._dispatch(EVT.INIT_ERROR, { message: this.labels.HAA_error_previewEnvironment });
return;
}

if (!this._hasValidConfig()) {
this._dispatch(EVT.INIT_ERROR, {
message: this.labels.HAA_error_invalidConfig
Expand Down Expand Up @@ -519,10 +538,10 @@ export default class HaaInlineEnhancedChat extends LightningElement {
this._initChat();
};
script.onerror = () => {
const isPreview = this._isSitePreview();
if (isPreview) this._isPreviewError = true;
this._dispatch(EVT.INIT_ERROR, {
message: this._isSitePreview()
? "Chat is not available in Experience Builder preview. Publish the site to test."
: this.labels.HAA_error_scriptLoadFailed
message: isPreview ? this.labels.HAA_error_previewEnvironment : this.labels.HAA_error_scriptLoadFailed
});
};
document.body.appendChild(script);
Expand Down Expand Up @@ -909,12 +928,15 @@ export default class HaaInlineEnhancedChat extends LightningElement {
}

_isSitePreview() {
// Match known Salesforce Experience Cloud builder/preview domains.
// Anchoring to salesforce-experience.com avoids false positives on
// customer-owned domains that might contain words like "preview" or "live".
return [
"sitepreview",
"livepreview",
"live-preview",
"live.",
".builder."
".builder.salesforce-experience.com",
".preview.salesforce-experience.com",
".live-preview.salesforce-experience.com",
".livepreview.salesforce-experience.com",
".sitepreview.salesforce-experience.com"
].some((s) => document.URL.includes(s));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>65.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
</targets>
</LightningComponentBundle>
<isExposed>false</isExposed>
Comment thread
dominic-butlerSFDC marked this conversation as resolved.
</LightningComponentBundle>