OpenCart Integration

Embed the PersoScan body map in OpenCart and navigate from a zone click to the matching category page, with the template hook and listener code to copy.

OpenCart is the most template-driven of these integrations, and the URL you map to depends on whether SEO URLs are switched on.

Prerequisites

  • You can edit page/template code in OpenCart.
  • You have category, tag, or collection pages ready for target redirects.
  • You can test in a published or preview storefront.

Where a zone click should land in OpenCart

With SEO URLs off, an OpenCart category is index.php?route=product/category&path=20_27, where the path is the category ID chain. With them on, the same page is whatever keyword you set, for example /knee-supports.

Search is the pragmatic alternative: index.php?route=product/search&search=knee+support. It needs no category structure at all, which makes it a decent fallback for zones you have not mapped yet, and a poor primary destination because relevance is at the mercy of your product titles.

Prefer category paths for the zones that matter and keep search for the fallback.

1. Prepare Zone Mapping

  1. Start with grouped zone IDs (head, neck, lower-back, and so on).
  2. Map each zone key to one destination URL or slug.
  3. Define a fallback destination for unmapped zones.

2. Embed And Listen

Add this code and update mapping values for your store:

<!-- Wrap the iframe in a div to control its dimensions.
     To fill an entire section, set both the div and iframe height to 100% instead. -->
<div style="height:650px;width:100%;">
<iframe
  id="persoscan-widget"
  src="https://widget.persoscan.com?license=your-license-key"
  style="width:100%;height:650px;border:none;border-radius:8px;color-scheme:light dark;"
  allow="fullscreen"
  title="PersoScan"
></iframe>
</div>

<script>
  var WIDGET_ORIGIN = new URL("https://widget.persoscan.com").origin;

  var zoneToCategoryUrl = {
    "head":           "head-care",
    "neck":           "neck-support",
    "upper-back":     "upper-back-support",
    "lower-back":     "lower-back-support",
    "left-shoulder":  "shoulder-support",
    "right-shoulder": "shoulder-support",
    "left-arm":       "arm-support",
    "right-arm":      "arm-support",
    "left-hand":      "hand-wrist-support",
    "right-hand":     "hand-wrist-support",
    "left-leg":       "leg-knee-support",
    "right-leg":      "leg-knee-support",
    "left-foot":      "foot-care",
    "right-foot":     "foot-care"
  };

  window.addEventListener("message", function(event) {
    if (event.origin !== WIDGET_ORIGIN) return;
    if (!event.data || event.data.source !== "persoscan-widget") return;
    if (event.data.type !== "zone-selected") return;

    var zoneId = event.data.data.zoneId;
    var categoryUrl = zoneToCategoryUrl[zoneId];

    if (categoryUrl) {
      window.location.href = "/" + categoryUrl;
    } else {
      // Fallback to search
      window.location.href = "/index.php?route=product/search";
    }
  });
</script>

3. Validate End-To-End

  1. Open the integration page.
  2. Click at least five mapped zones.
  3. Confirm each click redirects to the expected destination.
  4. Confirm unmapped zones use fallback destination.

Common Mistakes

Twig template change lost on theme update

Problem: The widget vanishes after an OpenCart or theme upgrade.

Cause: The snippet was pasted into a core template file, which the upgrade replaced.

Solution:

  1. Put the snippet in an Information page or a custom module, not in catalog/view/template/common/home.twig.
  2. If it has to live in a template, use a child theme directory so the override survives.

Origin mismatch blocks events

Problem: Clicks produce no redirects.

Cause: Event origin check does not match actual widget origin.

Solution:

  1. Derive origin from widget URL (new URL(WIDGET_URL).origin).
  2. Compare against event.origin.
  3. Keep strict source check (persoscan-widget).

Zone mapping keys do not match runtime keys

Problem: Some body parts never redirect.

Cause: Mapping object uses wrong key format.

Solution:

  1. Use exact zoneId values from Zone Reference.
  2. Keep keys lowercase with hyphen separators.

Next Steps

Last updated: March 12, 2026