# Crossdeck for Squarespace

> Source: https://cross-deck.com/docs/squarespace/ · Crossdeck developer docs (generated from the published page).

Setup
Paste-in Code Injection snippet · identity, custom domain, revenue
·
~5 min read
·
Updated August 5, 2026

Everything from install to identity to revenue. Paste one **Code Injection** snippet into your Squarespace site and it loads the Crossdeck web SDK on **every page** — so page analytics, journeys, and front-end error impact start flowing with no per-page work. The snippet is **paste-in**: you provision on Crossdeck, then edit two values in the snippet and save. This doc covers each step, plus the parts that need a decision from you: **the Business-plan requirement**, **best-effort identity**, **a custom domain**, and **connecting a payment rail** for revenue.

No marketplace, no review — it's a documented snippet.

Squarespace has **no site-script marketplace review**. Third-party SDKs are added through **Settings &rarr; Advanced &rarr; Code Injection** — the same documented path GA / Fathom / Plausible use. There is **no app to submit** and no approval email to wait on. Copy the snippet, fill in two values, save.

## TL;DR

- **Provision, then paste.** Create a project + app on Crossdeck (dashboard or `crossdeck init`), copy your **Publishable key** (`cd_pub_…`) and **App ID** (`app_…`), then add the snippet via **Settings &rarr; Advanced &rarr; Code Injection &rarr; Footer** and edit those two values.

- **Business plan or higher.** Site-wide Code Injection requires a Squarespace **Business** plan or above — it isn't on Personal plans.

- **No environment field.** The environment is derived from the key prefix (`cd_pub_test_` = sandbox, else production), so it can never be wrong.

- **Ingest-only key.** The snippet holds **only** the publishable key. Never paste a secret or workspace key (`cd_sk_` / `cd_wk_`).

- **Verify from the first real visit.** Save and publish, open the live site, click around, then watch a live visitor land in **Overview** / **People**. That first heartbeat also locks your Allowed Origins.

- **Custom domain = one 20-second step.** The origin lock happens on the first heartbeat, so a custom domain added later must be added to your [Allowed Origins](https://cross-deck.com/docs/allowed-origins/index.html) yourself.

- **Identity is best-effort.** Squarespace sites are anonymous by default. If a Member Areas / gated block renders the signed-in email, add `data-crossdeck-identify-email` to the element carrying it and the snippet calls `identify()` automatically.

- **Connect a rail for revenue.** Squarespace Commerce runs on Stripe — connect the **Stripe** rail so revenue and entitlements join the same identity graph as analytics and errors.

## What the connector does

Paste one **Code Injection** snippet and it loads the Crossdeck web SDK on **every page** of your Squarespace site — so page analytics, journeys, and front-end error impact start flowing with no per-page setup. Because Crossdeck joins **identity, revenue, errors, and analytics** on one identity graph, you can answer questions no single-layer tool can — for example, *&ldquo;which paying customers hit this error last week.&rdquo;*

The snippet holds only your **publishable key** (`cd_pub_`, ingest-only) plus your **App ID**. It loads `@cross-deck/web` from the CDN, calls `init({ appId, publicKey, environment })`, and makes a best-effort `identify()`. It is clean and safe by construction: an empty or wrong key is a silent no-op, an unreachable CDN is swallowed by `onerror`, and a page with no signed-in email simply stays anonymous.

## Step 1 — Install

### A. Provision on Crossdeck

- In the [Crossdeck dashboard](https://app.cross-deck.com) — or by running `crossdeck init` in the Crossdeck CLI — create a **project + app**.

- Copy your **Publishable key** (starts `cd_pub_`) and your **App ID** (starts `app_`).

### B. Paste the snippet into Squarespace

- In your Squarespace site, open **Settings** &rarr; **Advanced** &rarr; **Code Injection**.

- Paste the snippet below into the **Footer** box (the **Header** box works too — the loader is async). Both are site-wide, so it runs on every page.

- Click **Save**, then make sure the change is **published** to your live site.

Code Injection needs a Business plan or higher.

Site-wide Code Injection (Header/Footer) is a **Business**-plan-and-above feature on Squarespace — it isn't available on Personal plans. If you only need Crossdeck on certain pages, **Page Header Code Injection** (per page, via that page's settings) is an alternative, but the site-wide Footer is what this guide recommends.

### C. Edit the two values

Squarespace has no field-substitution for injected code, so you edit two values directly in the snippet: set `PUBLISHABLE_KEY` to your `cd_pub_…` key and `APP_ID` to your `app_…` ID. That's the only edit.

```
<!--
  Crossdeck for Squarespace — site-wide code injection
  ====================================================
  Add this ENTIRE block in Squarespace:
      Settings  →  Advanced  →  Code Injection  →  paste into "Footer"  →  Save
      (Header works too — the loader is async. Site-wide, runs on every page.)

  Requires a Squarespace BUSINESS plan or higher — Code Injection is not
  available on Personal plans.

  It loads the Crossdeck web SDK on every page of your Squarespace site and
  starts capturing page analytics, journeys, and front-end error impact — no
  per-page work. Squarespace has no field-substitution for injected code, so you
  fill in TWO values below (your Publishable key + App ID from the Crossdeck
  dashboard, or from `crossdeck init` in the CLI). That's the only edit.

  Environment is DERIVED from the key prefix (cd_pub_test_… = sandbox, anything
  else = production), so it can never disagree with the key.

  Clean + safe by construction:
    • only a PUBLISHABLE key (cd_pub_) is ever placed here — never a secret
    • not filled in / wrong key         → silent no-op, nothing loads
    • SDK CDN unreachable               → onerror swallows, no throw
    • identify has no logged-in email   → no-op (Squarespace sites are usually anon)
-->
<script>
  (function () {
    "use strict";

    // ── FILL IN THESE TWO VALUES ─────────────────────────────────────────────
    var PUBLISHABLE_KEY = "cd_pub_XXXXXXXXXXXXXXXXXXXXXXXX"; // from your Crossdeck dashboard
    var APP_ID          = "app_XXXXXXXXXXXX";                // from your Crossdeck dashboard
    // ─────────────────────────────────────────────────────────────────────────

    // Not configured, or a non-publishable key was pasted: do nothing at all.
    if (!PUBLISHABLE_KEY || !APP_ID || PUBLISHABLE_KEY.indexOf("cd_pub_") !== 0) return;

    var environment = PUBLISHABLE_KEY.indexOf("cd_pub_test_") === 0 ? "sandbox" : "production";

    function init() {
      try {
        if (window.Crossdeck && window.Crossdeck.Crossdeck) {
          window.Crossdeck.Crossdeck.init({
            appId: APP_ID,
            publicKey: PUBLISHABLE_KEY,
            environment: environment
          });
          identifyIfPossible();
        }
      } catch (e) { /* never surface to the console */ }
    }

    // Best-effort identity. Squarespace published sites expose no server-side
    // user client-side, so we look for an element that carries the signed-in
    // person's email: add the attribute `data-crossdeck-identify-email` to an
    // element (e.g. inside a Member Areas block) whose text/value is the email.
    // Absent that (a normal marketing site), this is a silent no-op.
    function identifyIfPossible() {
      try {
        var el = document.querySelector("[data-crossdeck-identify-email]");
        if (!el) return;
        var email = (el.getAttribute("data-crossdeck-identify-email") || el.textContent || "").trim();
        var CD = window.Crossdeck && window.Crossdeck.Crossdeck;
        if (email && CD && typeof CD.identify === "function") {
          CD.identify(email, { email: email });
        }
      } catch (e) { /* swallow */ }
    }

    if (window.Crossdeck && window.Crossdeck.Crossdeck) { init(); return; }
    var s = document.createElement("script");
    s.src = "https://unpkg.com/@cross-deck/web@1/dist/crossdeck.umd.min.js";
    s.async = true;
    s.onload = init;
    s.onerror = function () { /* CDN unreachable — fail silent, keep console clean */ };
    (document.head || document.documentElement).appendChild(s);
  })();
</script>
```

No environment field — it's derived from the key.

There is deliberately no environment setting. The environment is read from the key prefix (`cd_pub_test_…` = sandbox, anything else = production), so it can never disagree with the key. Until `PUBLISHABLE_KEY` holds a valid `cd_pub_` key and `APP_ID` is set, the snippet loads nothing — zero cost and a clean console.

Publishable key only.

The snippet holds **only** your publishable, ingest-only key (`cd_pub_`) — it cannot read or change your Crossdeck account. Never paste a secret or workspace key (`cd_sk_` / `cd_wk_`). Provisioning happens on the Crossdeck engine, never in the Squarespace site.

## Step 2 — Verify it's working

**Save and publish**, open your live site, and click around. Crossdeck's first heartbeat **auto-learns your site's origin**. Then open the Crossdeck dashboard &rarr; **Overview** / **People** — you'll see a live visitor with geo, and the pages they viewed. (Data begins from the **first real visit** — that first heartbeat also locks your Allowed Origins to that domain.)

Nothing showing yet?

Check that you edited both `PUBLISHABLE_KEY` (`cd_pub_…`) and `APP_ID` (`app_…`) in the snippet, that you **saved** Code Injection and are on a plan that supports it, and that the environment you're viewing in the dashboard matches the app/key. The first heartbeat can take a few moments.

## Step 3 — Custom domain

When you move to or add a custom domain, add it to your Allowed Origins — 20 seconds, and it pulls you into the dashboard:

&rarr; [Add a domain to your Allowed Origins](https://cross-deck.com/docs/allowed-origins/index.html)

The origin lock happens on the first heartbeat — then it locks.

A Squarespace site first served on its `*.squarespace.com` address learns *that* origin on its first heartbeat. It will **not** auto-learn a custom domain you add *later* — you must add the custom domain to your Allowed Origins yourself, or traffic from it won't be accepted.

## Step 4 — Identity (best-effort on Squarespace)

Analytics works anonymously out of the box. Squarespace published sites expose **no server-side user** to client code — and a Squarespace site is usually a marketing site — so identity is **best-effort**, not automatic. This is the honest difference from WordPress, where a server-side login hook resolves users for you. Don't expect automatic identity on Squarespace; anonymous analytics is the default and often exactly right.

If your site *does* have a **Member Areas** / gated block that renders the signed-in person's email, you can turn those visitors into **known people** — the same mechanism the Framer and Webflow connectors use:

- Find the element that displays the signed-in person's email (for example, inside a members-only block).

- Add the attribute `data-crossdeck-identify-email` to that element — either carrying the email as its value, or wrapping the element whose text is the email.

- Save and publish. On each page load the snippet looks for that attribute and, if it finds an email, calls `identify(email)` automatically.

Absent that attribute (a normal marketing site), `identify()` is a clean **no-op** and analytics simply stays anonymous — nothing to configure and nothing that errors.

Why email is the anchor.

Crossdeck keys identity on **email** — the no-backend join rail — so the email you expose via `data-crossdeck-identify-email` is what joins this visitor to the same person across revenue, errors, and analytics. (See [How identity works](https://cross-deck.com/docs/how-identity-works/index.html) for the full model.)

## Step 5 — Revenue (connect a payment rail)

Squarespace Commerce runs on **Stripe**, so revenue joins through the Stripe rail — no Squarespace-specific ingest needed. To join **revenue** to those people:

- In the Crossdeck dashboard, open **Developers &rarr; Rails** (Payment rails).

- Connect **Stripe** in one click — Crossdeck never asks for a raw secret key.

- Stamp the Crossdeck reference onto your checkout / subscription events so each payment threads back to the right person. See **Rails &rarr; Stripe** in the dashboard for the exact one-liner.

Once the rail is connected, revenue and entitlements join the same identity graph as your analytics and errors. (Sending revenue events is done from your Crossdeck account setup — not from the Squarespace snippet.)

## How this differs from the other connectors

- **Squarespace** (this): add the snippet via **Settings &rarr; Advanced &rarr; Code Injection** (Business plan or higher) and edit two values. Identity best-effort via a `data-crossdeck-identify-email` attribute; revenue via the Stripe rail.

- **Framer:** add a **Custom Code** snippet via **Settings &rarr; Code** and edit two values (no plan gate). Identity best-effort via `data-crossdeck-identify-email`.

- **Wix:** one-click App Market install &rarr; project + keys auto-created &rarr; SDK injected, plus automatic Wix Stores revenue. Identity for Members via a Velo snippet.

- **WordPress:** install the plugin. Identity is **automatic** — a server-side login hook resolves the signed-in user for you.

- **Webflow:** one-click OAuth marketplace install &rarr; account + project auto-created &rarr; SDK injected. Identity via a `data-crossdeck-identify-email` binding.

Every connector loads the **same** Crossdeck SDK and feeds the **same** dashboard — only the install + identity binding differ per platform.

Crossdeck for Squarespace — paste-in Code Injection snippet via Settings &rarr; Advanced &rarr; Code Injection (edit Publishable key + App ID, Business plan or higher), SDK loaded on every page, environment derived from the key prefix, custom-domain add via [Allowed Origins](https://cross-deck.com/docs/allowed-origins/index.html), best-effort identity via `data-crossdeck-identify-email`, and revenue on a connected Stripe rail (August 5, 2026). Related: [Identify users](https://cross-deck.com/docs/identify-users/index.html), [Connect Stripe](https://cross-deck.com/docs/connect-stripe/index.html).
