SeloraXDEVELOPERS

Storefront Extensions Overview

Storefront Extensions

Storefront extensions let apps inject UI directly into the customer-facing store — product pages, checkout, homepage, cart, header, and footer. Unlike dashboard extensions which only merchants see, storefront extensions are visible to shoppers.

There are two rendering modes (same as dashboard extensions):

  • JSON mode — Declarative UI tree rendered natively by the storefront. No iframe, no hosting. 35+ components including storefront-specific widgets like ratings, countdown timers, trust badges, and product cards.
  • Sandbox mode — Your JavaScript runs inside an isolated <iframe sandbox="allow-scripts">. You control rendering, communicate via postMessage.

Storefront Targets

Every storefront extension declares a target starting with storefront. — this determines where it renders on the store.

TargetTypeDescription
storefront.product.blockBlockWidget below product details (reviews, badges, upsells)
storefront.product.actionActionAction button on product page
storefront.cart.blockBlockWidget in the cart
storefront.checkout.blockBlockWidget on checkout (upsells, trust badges, custom fields)
storefront.homepage.blockBlockSection on the homepage
storefront.global.embedEmbedFloating widget on all pages (chat bubbles, popups)
storefront.header.blockBlockBanner or announcement above the header
storefront.footer.blockBlockWidget above the footer
storefront.thankyou.blockBlockPost-purchase widget on the thank-you page

How It Works

1. App registers extension with a storefront.* target
2. App is installed by a store
3. Storefront fetches extensions via GET /api/apps/extensions/storefront
4. StorefrontSlot renders each extension with the StorefrontRenderer
5. Extensions receive page context (product_id, store_id, cart data, etc.)
6. Actions (button clicks) are proxied to your backend via POST /api/apps/extensions/storefront/action

Key Differences from Dashboard Extensions

FeatureDashboardStorefront
AudienceMerchants/adminsShoppers/customers
AuthenticationRequires admin JWTPublic (no auth)
API endpointGET /api/apps/extensions/pageGET /api/apps/extensions/storefront
Action proxyPOST /api/apps/extensions/actionPOST /api/apps/extensions/storefront/action
Component count74 components35+ components (storefront-optimized)
Available contextOrder data, customer detailsProduct info, cart state, visitor status
Caching5-minute React Query stale time5-minute sessionStorage cache
Lazy loadingNoYes (IntersectionObserver, 200px pre-load)
Cart integrationNoYes (add_to_cart action bridges to Redux)
AnalyticsNo built-in trackingAutomatic impression, click, action tracking

Public API Endpoints

Fetch Storefront Extensions

GET /api/apps/extensions/storefront?store_id={id}&targets={target1},{target2}

No authentication required. Only accepts storefront.* targets — admin targets are rejected with 400.

Response:

{
  "status": 200,
  "data": {
    "storefront.product.block": [
      {
        "extension_id": "my-reviews",
        "app_id": 42,
        "target": "storefront.product.block",
        "title": "Customer Reviews",
        "mode": "json",
        "ui": { "type": "Card", "children": [...] },
        "initial_state": {},
        "installation_id": 99,
        "app_name": "ReviewApp",
        "app_slug": "review-app"
      }
    ]
  }
}

Storefront Action Proxy

POST /api/apps/extensions/storefront/action

No authentication required. Validates installation_id + store_id against the database. Only works for apps with active storefront.* extensions.

Request body:

{
  "installation_id": 99,
  "store_id": 3,
  "action_url": "https://myapp.com/api/reviews/submit",
  "method": "POST",
  "body": { "product_id": 42, "rating": 5, "comment": "Great!" }
}

The backend generates a session token and forwards the request to your app with:

  • Authorization: Bearer <session_token> header
  • X-SeloraX-Store-Id header
  • X-SeloraX-Installation-Id header
  • X-SeloraX-Source: storefront header (so you can distinguish storefront vs admin requests)

Rate limited: 60 requests per minute per installation.

SSRF protection: action_url hostname must match your app's registered app_url.

Response Directives

Your app backend can return directives that the storefront automatically processes:

{
  "show_toast": { "message": "Review submitted!", "type": "success" },
  "update_state": { "submitted": true, "review_count": 43 },
  "update_ui": { "type": "Card", "children": [...] },
  "navigate": { "url": "/products/other-product" },
  "open_link": { "url": "https://example.com" },
  "refresh_extensions": true
}
DirectiveEffect
show_toastShows a toast notification to the shopper
update_stateMerges new state into the extension's local state
update_uiReplaces the extension's entire UI tree
navigateRedirects the page (only http://, https://, / URLs allowed)
open_linkOpens a URL in a new tab
refresh_extensionsClears cache and re-fetches all extensions in this slot