# Crossdeck for Bubble

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

Setup
Paste-key SDK install · identity, custom domain, revenue
·
~5 min read
·
Updated August 4, 2026

Everything from install to identity to revenue. Install the Crossdeck plugin and it loads the Crossdeck web SDK on **every page** of your Bubble app — so page analytics, journeys, and front-end error impact start flowing with no code. The plugin is **paste-key**: you provision on Crossdeck, then paste two values into the plugin. This doc covers each step, plus the parts that need a decision from you: **identity via a workflow action**, **a custom domain**, and **connecting a payment rail** for revenue.

## 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_…`), and paste both into **Plugins &rarr; Crossdeck**. No code, no per-page work.

- **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 plugin holds **only** the publishable key. Never paste a secret or workspace key (`cd_sk_` / `cd_wk_`).

- **Verify from the first real visit.** Run the app, 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.

- **Turn users into known people.** Add the **&ldquo;Crossdeck – Identify user&rdquo;** workflow action with **Email = Current User's email** and Crossdeck resolves signed-in users.

- **Connect a rail for revenue.** Connect Stripe (or Apple / Google) so revenue and entitlements join the same identity graph as analytics and errors.

## What the connector does

Install the Crossdeck plugin and it loads the Crossdeck web SDK on **every page** of your Bubble app via the plugin's **Shared HTML header** — so page analytics, journeys, and front-end error impact start flowing with no code and 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;*

Paste-key, not OAuth.

Unlike the Webflow connector (a one-click OAuth marketplace install), the Bubble plugin is **paste-key**: you provision keys on Crossdeck, then paste your **Publishable key** and **App ID** into the plugin. Same SDK, same dashboard — just a two-field install.

## 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. Install the plugin on your Bubble app

- In your Bubble editor, open the **Plugins** tab and add **Crossdeck — Revenue, Identity & Error Analytics**.

### C. Paste your two values

- Open **Plugins &rarr; Crossdeck**.

- Paste your **Publishable key** into the **Publishable key** field and your **App ID** into the **App ID** field. That's it — the SDK loads on every page via the plugin's shared header.

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 both fields hold a valid `cd_pub_` key, the plugin loads nothing — zero cost and a clean console.

Publishable key only.

The plugin 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 Bubble app.

## Step 2 — Verify it's working

**Run your app** (not just the editor preview) and click around. Crossdeck's first heartbeat **auto-learns your app'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 both the **Publishable key** (`cd_pub_…`) and **App ID** (`app_…`) are entered, that you've **run** the app (not just previewed the editor), 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 Bubble app first served on `*.bubbleapps.io` 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 (resolve logged-in users)

Analytics works anonymously out of the box. To turn anonymous visitors into **known people** — the Crossdeck cross — Crossdeck needs your logged-in user's email. Bubble exposes **Current User** to **workflows**, not to arbitrary header JS, so identity is a **workflow action**, not header code. You add it once:

- In a workflow that fires when someone is **signed in** — the page's **&ldquo;Current User is logged in&rdquo;** event, or the step right after your **Log the user in** action — add **Plugins &rarr; Crossdeck – Identify user**.

- Set **Email** &rarr; `Current User's email` (required).

- Optionally set **User ID** &rarr; `Current User's unique id`.

That's it. The action is **idempotent**, so it's safe to run on every page load; if no one is signed in it does nothing (no error). Signed-in users now resolve to known people in **People**. This mirrors the Webflow connector's `identify()` exactly.

### Wire it into your sign-up & log-in workflows

Bubble's built-in **User** type already has email + password, so you don't need another plugin for auth. Add the Identify step to *both* entry points, so a person resolves the moment they sign up and every time they log back in:

- **Sign-up workflow.** On your **Sign up** button: **Account &rarr; Sign the user up** (Email = your email input's value, Password = your password input's value). Then **add a next step** &rarr; **Plugins &rarr; Crossdeck – Identify user** and set **Email = `Current User's email`**.

- **Log-in workflow.** On your **Log in** button: **Account &rarr; Log the user in** (same email + password inputs). Then **add a next step** &rarr; **Crossdeck – Identify user** and set **Email = `Current User's email`**.

- **(Recommended) Every authenticated page load.** On the page, add the event **&ldquo;Current User is logged in&rdquo;** &rarr; **Crossdeck – Identify user** &rarr; **Email = `Current User's email`**. Idempotent, so re-running it costs nothing.

Always bind, never type.

Set the **Email** field with **Insert dynamic data &rarr; Current User's email** — never a hardcoded address. A typed literal identifies one fake person; `Current User's email` resolves the *real* signed-in user, which is the whole point.

Why email is the anchor.

Crossdeck keys identity on **email** — the no-backend join rail — so email always rides along as a trait to keep the identity graph joined. When you also provide a stable **User ID** (Current User's unique id), that id **outranks** email in Crossdeck's resolver and is used as the key. (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)

To join **revenue** to those people:

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

- Connect **Stripe** (or Apple / Google) 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 a 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 Bubble plugin.)

## How this differs from the other connectors

- **Bubble** (this): paste your **Publishable key** + **App ID** into the plugin. Identity via the **&ldquo;Crossdeck – Identify user&rdquo;** workflow action (Bubble exposes Current User to workflows).

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

- **WordPress:** install the plugin, connect (or paste keys). Identity via the WordPress user hook.

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

Crossdeck for Bubble — paste-key plugin install (Publishable key + App ID), SDK loaded on every page via the shared header, environment derived from the key prefix, custom-domain add via [Allowed Origins](https://cross-deck.com/docs/allowed-origins/index.html), identity via the &ldquo;Crossdeck – Identify user&rdquo; workflow action, and revenue on a connected rail (August 4, 2026). Related: [Identify users](https://cross-deck.com/docs/identify-users/index.html), [Connect Stripe](https://cross-deck.com/docs/connect-stripe/index.html).
