Skip to content
Log in

Embed Salesforce LWC components in your storefront

On this page

StoreConnect storefronts use a Liquid-based theme engine, but you can also embed Salesforce Lightning Web Components (LWC) directly into your storefront pages. This lets you bring Salesforce-native UI and logic into your store without rebuilding it in Liquid or JavaScript.

This can be achieved using Salesforce Lightning Out combined with a secure, token-based authentication layer. The StoreConnect theme generates an HMAC-signed token server-side, and a wrapper LWC on the Salesforce side verifies the token before dynamically rendering your component with authenticated customer data. Depending on your setup, there are also other ways to approach this.

A ready-to-deploy proof of concept project is available for download:

Download the StoreConnect Secure LWC project

How it works

The embedding process follows a secure handshake between StoreConnect and Salesforce:

  1. Token generation (StoreConnect) – When a storefront page loads, the Liquid template generates a JSON payload containing the customer’s context (Customer ID, Store ID) and a timestamp. This payload is cryptographically signed using HMAC-SHA256 with a shared secret stored in Store Variables. The resulting token is embedded into the page HTML.

  2. Client-side loading – The browser loads the Salesforce Lightning Out library via a singleton loader (preventing duplicate script loads when multiple components are on the same page). A wrapper LWC is initialized and receives the signed token along with the name of the component to render.

  3. Server-side verification (Salesforce) – The wrapper LWC passes the token to an Apex controller. Apex retrieves the shared secret for the originating store, recalculates the HMAC signature, and verifies it matches. It also checks that the token has not expired (1-hour window with 30-second clock skew tolerance).

  4. Dynamic rendering – Once verified, the wrapper dynamically instantiates the requested business component and passes the authenticated customer data down to it. The component renders inside the storefront page.

StoreConnect Salesforce +------------------------------+ +-----------------------------------+ | 1. Page loads | | | | 2. Liquid generates | | | | HMAC-signed token | | | | 3. Token embedded in HTML | | | | | | | | 4. Browser loads | ------> | 5. Wrapper LWC receives token | | Lightning Out library | | + component name | | | | | | | | 6. Apex validates: | | | | - Retrieve store secret | | | | - Verify HMAC signature | | | | - Check token expiry | | | | | | | <------ | 7. Render requested component | | 8. Resize and error events | <------ | with authenticated data | | via postMessage | | | +------------------------------+ +-----------------------------------+

Security features

  • Tamper-proof – Any modification to the token (for example, changing the Customer ID) invalidates the signature and causes immediate rejection.
  • Zero-trust – No secrets or API keys are ever exposed to the client browser. The HMAC secret exists only server-side in Store Variables and in the Salesforce Store_Variable__c record.
  • Cache compatible – The stateless design (timestamp + signature) works with StoreConnect’s page caching without triggering false security errors.
  • Component allowlist – Only explicitly registered components can be loaded. The wrapper uses a COMPONENT_MAP object as a security gate, preventing arbitrary component injection.
  • Constant-time comparison – Signature verification uses constant-time string comparison to prevent timing attacks.
  • Token expiry – Tokens are valid for 1 hour from generation, with a 30-second clock skew tolerance for server time differences.

Alternative approaches

Depending on what you are building, you may not need LWC embedding at all. StoreConnect provides several ways to add custom functionality to your storefront:

  • Liquid templates with custom JavaScript – Full control over markup and scripting using the theme engine. See Adding custom JavaScript, CSS and head content.
  • Content blocks with raw HTML/JS – Use the “No added styling” content block template to insert custom HTML and JavaScript. See Content block templates.
  • Server-side API proxy – Use Liquid’s api tag and Store Variables to call external APIs server-side without exposing credentials. This is useful for fetching and displaying data from third-party services.

LWC embedding is best suited for scenarios where you need to reuse existing Salesforce components, access Salesforce data in real time through Apex, or leverage the Lightning component ecosystem on your storefront.

Prerequisites

Before you begin, you need:

  • A Salesforce org with the StoreConnect managed package installed
  • Salesforce CLI (sf) installed locally
  • An Experience Cloud site configured in your Salesforce org (this provides the Lightning Out endpoint)
  • Access to your StoreConnect theme files

What is in the project

The downloadable project contains everything needed to get LWC embedding working:

File Purpose
templates/blocks/lwc.liquid Liquid content block template for your StoreConnect theme. Handles token generation and Lightning Out initialization.
force-app/main/default/classes/StoreConnectAuthHandler.cls Apex class that validates HMAC-signed tokens. Retrieves the shared secret from Store Variables, verifies the signature, and checks token expiry.
force-app/main/default/classes/StoreConnectAuthHandlerTest.cls Apex test class covering valid tokens, expired tokens, tampered signatures, and invalid store IDs.
force-app/main/default/lwc/storeConnectWrapper/ Wrapper LWC that authenticates the token via Apex, then dynamically renders the requested component. Uses a component allowlist for security.
force-app/main/default/aura/StoreConnectLWCOut/ Lightning Out Aura application. This is a Salesforce requirement for serving LWC components externally.
README.md Full setup instructions, architecture overview, and development commands.

Set up Salesforce

Step 1: Configure the shared secret in Salesforce

Create a Store_Variable__c record for each store that will embed LWC components:

Field Value
Store_Id__c Your StoreConnect Store ID
Key__c SC_HMAC_Secret
Value__c A strong, random secret string
Available_In_Liquid__c true

:::note The secret must be identical on both the Salesforce and StoreConnect sides. Generate a strong random string (at least 32 characters) and keep it secure. :::

Step 2: Deploy the Apex and LWC components

From the project directory, deploy to your Salesforce org:

bash sf project deploy start --source-dir force-app

This deploys: - The StoreConnectAuthHandler Apex class and its test class - The storeConnectWrapper LWC - The StoreConnectLWCOut Aura application

Step 3: Set up an Experience Cloud site

If you do not already have an Experience Cloud site, create one in Salesforce Setup under Digital Experiences > All Sites. This site provides the Lightning Out endpoint URL that StoreConnect uses to load components.

Note the following URLs from your Experience Cloud site: - Lightning Out script URLhttps://{your-domain}.my.site.com/lightning/lightning.out.js - Experience Cloud site URLhttps://{your-domain}.my.site.com

Set up StoreConnect

Step 1: Configure Store Variables

In your StoreConnect admin, create three Store Variables:

Store Variable Description Example value
SC_HMAC_Secret The shared HMAC secret (must match the value in Salesforce) A strong random string (at least 32 characters)
SF_My_Salesforce Lightning Out script URL from your Experience Cloud site https://yourdomain.my.site.com/lightning/lightning.out.js
SF_My_Experience Your Experience Cloud site URL https://yourdomain.my.site.com

Step 2: Add the Liquid template to your theme

Copy templates/blocks/lwc.liquid from the project into your StoreConnect theme’s templates directory at templates/blocks/lwc.liquid.

This creates a new content block template called lwc that you can use to embed components.

Step 3: Create a content block template option

In Salesforce, add lwc as a new picklist value to the Content_Block__c.Template__c field. This makes the template available when creating content blocks.

Step 4: Embed a component

Create a content block in StoreConnect and:

  1. Set the Template to lwc
  2. Set the Content field to the name of the component you want to render (for example, contactSupportForm)

The Liquid template reads the component name from the content block, generates a signed token, and handles the Lightning Out initialization automatically.

Register custom components

The wrapper uses a component allowlist for security. Only components explicitly imported and registered in the COMPONENT_MAP can be loaded.

To add a new embeddable component:

  1. Create your LWC under force-app/main/default/lwc/ in your Salesforce org.
  2. Import it in storeConnectWrapper.js and add it to the COMPONENT_MAP:

```javascript import MyComponent from ‘c/myComponent’;

const COMPONENT_MAP = { // …existing components ‘myComponent’: MyComponent, }; ```

  1. Your component receives authData as a property containing all token claims:

```javascript // In your custom component import { LightningElement, api } from ‘lwc’;

export default class MyComponent extends LightningElement { @api authData; // Contains: isValid, customerId, and any custom claims } ```

  1. Deploy the updated wrapper and your new component to your Salesforce org.
  2. Reference the component name in a StoreConnect content block using the lwc template.

:::tip You can embed multiple LWC components on the same page. Each content block gets its own container, token, and event scope. :::

Token structure

The token generated by the Liquid template follows this format:

{storeId}|v1.{base64-encoded-payload}.{hex-hmac-signature}

The payload contains standard claims:

Claim Description
aud Store domain (audience)
exp Expiry timestamp (1 hour from generation)
iat Issued-at timestamp
jti Nonce (store + customer + time + block ID for uniqueness)
sub Customer ID, or guest for unauthenticated visitors

Auto-resizing

The wrapper LWC uses a ResizeObserver to monitor the rendered component’s height and sends postMessage events back to the storefront. The Liquid template listens for these events and adjusts the container height automatically. This means embedded components resize smoothly without scrollbars or fixed heights.

Error events (SC_AUTH_ERROR) are also sent via postMessage and logged to the browser console, scoped to the specific component name.

Troubleshooting

Component does not render

  • Verify the component name in the content block exactly matches a key in the COMPONENT_MAP in storeConnectWrapper.js
  • Check the browser console for authentication errors
  • Confirm the Experience Cloud site is published and accessible

Authentication errors

  • Confirm the SC_HMAC_Secret value is identical in both StoreConnect Store Variables and the Salesforce Store_Variable__c record
  • Check that the Store_Id__c on the Salesforce record matches your StoreConnect Store ID
  • If you see “Token expired” errors, verify that your server clocks are reasonably in sync (the system allows 30 seconds of skew)

Lightning Out script fails to load

  • Verify the SF_My_Salesforce Store Variable contains the correct URL ending in /lightning/lightning.out.js
  • Confirm the Experience Cloud site is published and the URL in SF_My_Experience is correct
  • Check for Content Security Policy (CSP) errors in the browser console – you may need to add your Salesforce domain to your store’s CSP trusted sites

Multiple components on the same page

Each content block generates its own unique container ID and token. The postMessage events include the component name so resize and error events are scoped correctly. If components are interfering with each other, check that each content block has a unique identifier.

Was this article helpful?

Was this article helpful?