Squarespace Integration

Use a Squarespace code block to embed the PersoScan body map and map each zone click to a category page, with the exact snippet and the caveats to expect.

Squarespace is the fastest of these to get working and the easiest to get wrong, because the editor preview does not behave like the published site.

Prerequisites

  • You can edit page/template code in Squarespace.
  • 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 Squarespace

Squarespace commerce filtering runs on tags, not categories, so the natural destination is the shop page with a tag query: /shop?tag=knee. Tag names in the URL are case sensitive and space sensitive, so a tag called Knee Support becomes ?tag=Knee%20Support, which is why the snippet maps zone keys to exact tag strings rather than building them from the zone name.

If you would rather use real pages, a Squarespace category page works too, at /shop/category-name. Fewer moving parts, but you lose the many-to-many that tags give you.

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 zoneToTag = {
    "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",
    "right-hand":     "hand-wrist",
    "left-leg":       "leg-knee",
    "right-leg":      "leg-knee",
    "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 tag = zoneToTag[zoneId];

    if (tag) {
      window.location.href = "/shop?tag=" + tag;
    } else {
      window.location.href = "/shop";
    }
  });
</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

Code block stripped on save

Problem: The widget disappears after editing an unrelated part of the page.

Cause: Some Squarespace plans and some block types sanitise script tags on save.

Solution:

  1. Use a Code block with the language set to HTML, not a text block.
  2. Confirm your plan includes code injection, on the lower tiers it does not.

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