Skip to content

Support messenger embed

When your organization connects a customer-support provider, litecommerce exposes your catalog to that provider so its AI agent can answer shopper questions with live data. Customer-scoped answers — order status, shipments, bookings — are a later release; see below.

The messenger widget itself is yours to embed. litecommerce does not serve it, inject it, or require any @litecommerce/* package on your storefront. You add the provider's own snippet to your own pages. This guide covers what that takes and — more usefully — the two things that catch teams out: an enforcing Content-Security-Policy, and environment separation.

Intercom is the currently supported provider, so the concrete examples name it. The contract below is what litecommerce guarantees; the snippet and host names come from your provider's documentation.

The environment rule (read this first)

One provider workspace binds to exactly one litecommerce environment at a time. This is enforced in the platform, not merely recommended — a workspace cannot be connected to beta and production simultaneously.

The consequence is the thing to internalize:

Never embed the messenger on your production storefront while its workspace is connected to the beta API. If you do, real customers get answers built from beta catalog data — beta prices, beta availability — presented as current fact. The AI agent has no way to know or say that the numbers are from the wrong environment.

So while you are piloting against beta:

SurfaceMessenger
Your beta/staging storefrontYes — this is where you test
Your production storefrontNo — and there is no cutover available yet; see below

Production support-provider connections are not available yet. They are gated off in litecommerce pending a general-availability decision, so there is currently no production workspace to cut over to. Do not release a working beta connection expecting to replace it — you would be left with neither. Treat the pilot as beta-only until your operator tells you the gate has opened.

When it does open, promoting will be a cutover, not a settings edit: because a workspace can hold only one connection, the beta connection is released and a new production one established, with a new credential and fresh verification. There is no window in which both are live, so it is a scheduled, operator-run step rather than something a tenant performs alone.

More generally: do not mix production and beta surfaces in one flow. A support answer that draws policy text from your production help content and prices from the beta API is wrong in a way that is very hard to notice, because each half looks right on its own.

Prerequisites

Before the embed does anything useful:

  1. A connected provider workspace. Your litecommerce operator establishes this; you will be told which workspace is connected and to which environment.
  2. The AI agent deployed on the messenger channel. This is the step most often missed. A workspace can have a working connector and a working messenger while the agent itself is not live — in which case the widget opens and routes conversations to your inbox, and the agent never answers. Check the provider's agent status explicitly rather than inferring it from the connector being healthy.
  3. Knowledge content, if you want policy answers. The catalog connector answers product questions. Shipping policy, returns policy, and FAQ answers come from content you sync into the provider's knowledge base, not from litecommerce.

On that last point, one recommendation: do not sync your product pages into the provider's knowledge base. Rendered product pages contain prices and availability that go stale, and the agent will happily answer from stale knowledge instead of calling the live connector. Sync policy and editorial content; let the connector own price and stock.

The embed

Add your provider's snippet to your storefront layout, scoped to the pages where you want the messenger available. Nothing in it is litecommerce-specific — it is the provider's standard install, carrying the provider's workspace or app id.

For anonymous visitors that is the entire requirement. No identity token, no signing key, no litecommerce call.

Content-Security-Policy

If your storefront enforces a CSP, the snippet alone will not work, and the failure is noisy but easy to misread: the widget silently never appears, and the console fills with policy violations.

A messenger widget is not a single script. At runtime it loads further scripts, opens XHR and WebSocket connections, pulls images and fonts from its own CDNs, injects styles, and renders parts of itself in frames. An enforcing policy has to permit all of that.

Expect to add allowances across these directives:

DirectiveWhy the messenger needs it
script-srcthe loader plus the widget bundles it fetches at runtime
connect-srcAPI calls and wss: WebSocket endpoints for live conversation
img-srcavatars, uploaded attachments, agent and brand assets
font-srcthe widget's own webfonts
style-srcinline styles, including style attributes — see below
frame-srcembedded content the widget renders in frames
media-srcaudio or video attachments, if you allow them

Take the exact host names from your provider's current CSP documentation. They change, and a stale allow-list copied from a blog post is both a security regression and a support ticket.

Host allowances and inline content are different problems

This distinction matters more than the host list, and getting it wrong costs an afternoon.

Runtime-loaded resources — the bundles the widget fetches, its fonts, its images — are covered by adding the provider's origins to the matching directive. That is what the table above is for.

Runtime-injected inline content is not. Adding an origin to style-src does nothing for an inline style, because an origin describes where a resource may be fetched from and inline content is not fetched from anywhere. Inline content needs a nonce, a hash, or 'unsafe-inline'.

And a nonce does not always rescue you. Inline style attributes — styles set directly on an element rather than in a <style> block — cannot carry a nonce.

They can, narrowly, be hashed: CSP Level 3 authorizes an exact attribute value by hash when combined with the 'unsafe-hashes' source expression. That is a real option worth knowing about, and it is far narrower than blanket 'unsafe-inline' — but it only works for attribute values that are stable enough to pre-hash. A widget that computes positions and dimensions at runtime produces values that change, so there is nothing fixed to hash.

For that dynamic case, expect to allow 'unsafe-inline' on style-src, and treat it as a deliberate decision rather than a detail. It is a genuine relaxation of a policy you tightened on purpose. The practical exposure is limited — style injection mostly affects appearance and can assist social engineering, rather than executing code — but you should be the one deciding that, not discovering it. Check your provider's current CSP documentation before assuming which case you are in.

Note that this does not extend to script-src. Do not relax that directive to make a widget work; if a provider appears to require 'unsafe-inline' or 'unsafe-eval' for scripts, verify it against their documentation before accepting it.

Two more practical notes

  • Stage it in report-only. Deploy the additions as Content-Security-Policy-Report-Only first, exercise the widget end to end — open it, send a message, upload an attachment, let the agent answer — and read the reports before enforcing. Opening the widget alone does not exercise every origin it eventually needs.
  • Keep host additions scoped to the messenger's own origins. Widening a directive to a wildcard to make a widget work removes the protection the policy exists for.

What the agent can answer

Anonymous — public catalog

With only the messenger embedded, the agent can answer product questions from your live catalog: what exists, what it costs, whether it is in stock, and where to view it. The data is the same public projection your storefront reads, so it cannot expose anything a visitor could not already see.

Two limits worth setting expectations on:

  • The catalog connector is read-only. It cannot add to cart, start a checkout, apply a discount, or place an order. Answers can link a shopper to a product page; they cannot transact.
  • Availability of anonymous answers depends on your provider's customer authentication rules. Providers gate connector calls by rules scoped to channel and audience — visitors, leads, and identified users are treated differently, and a rule requiring verification will challenge a shopper before the agent answers. If you want anonymous product questions answered without a challenge, confirm your rules do not require verification for visitors.

Authenticated — customer context (planned, not yet available)

Not available today. Do not build against this section yet. litecommerce serves no customer-context route and no token-mint route for support providers. There is nothing for an operator to enable, and a storefront that implements this flow now has nothing to call. It is documented here so the constraints are known in advance, not because it can be integrated.

Order status, shipment tracking, booking details, and order history all require the agent to know which customer it is talking to — and require litecommerce to verify that, rather than take the provider's word for it. That verification contract, the routes behind it, and their OpenAPI surface land together in a later release. This page will document the flow when they do.

One principle is worth knowing now, because it shapes what you should and should not accept from a provider in the meantime:

Never build customer-scoped answers on an unverified identity. A provider may pass a customer's email in a request header whose name suggests it is verified. Whether it actually is depends on that workspace's authentication rules — and a header is a claim, not proof. Any endpoint of yours that returns customer data on the strength of such a header can be asked for somebody else's data. litecommerce will require verifiable identity for customer-scoped context precisely so that a misconfigured rule in a support tool cannot become a way to read another customer's orders.

If you are planning work that depends on this, talk to your litecommerce operator about sequencing rather than building ahead of the contract.

Privacy and cookies

An embedded messenger sets its own cookies and processes visitor data under the provider's terms, not litecommerce's. Your privacy notice and cookie disclosure need to reflect that, and if you operate a consent banner, decide deliberately whether the messenger loads before or after consent. Loading it before consent is a choice with legal consequences in some jurisdictions; make it on purpose.

Verifying the embed works

Check these in order — each one fails differently:

  1. The widget renders. If not, look at the console for CSP violations before anything else.
  2. A message reaches the provider. Confirm the conversation appears in the provider's inbox.
  3. The AI agent responds at all. If a human inbox receives it and no agent replies, the agent is not live on that channel.
  4. The agent calls the connector. Ask a product question whose answer the agent cannot know from synced content — a specific price, or stock on a specific variant. Then check the provider's connector logs for an execution attributed to the agent.
  5. The answer matches your catalog. Compare the quoted price against your storefront. A price that matches nothing in your data usually means the agent answered from sample or example data rather than a live call — check the connector log rather than trusting the answer.

Step 5 is worth doing deliberately. An agent quoting a confident, specific, wrong price is harder to spot than one that fails outright, and a preview or test mode that substitutes example data will produce exactly that.