JavaScript API (Widget Events) #

Beyond the REST API, the embedded eCard Widget dispatches browser CustomEvents you can listen for on the page where the widget is embedded. Use them to run analytics, customize the send experience, or trigger your own actions when someone shares an eCard — no server needed.

All events fire on document. Listen with document.addEventListener('<event>', handler).

You can also pass data into the widget: see Custom merge tags to attach your own key/value data to every send and use it as [merge_tags] in the eCard.

Tip: while developing, console.log(e.detail) inside any handler to inspect exactly what's available.


Events at a glance #

Event Fires when e.detail gives you
ecwWidgetLoaded the widget finishes loading widgetid, store()
ecwWidgetLoaded_<vanityId> same, but scoped to one widget widgetid, store()
ecwOpenEcardForm the send form opens (after an eCard is chosen) ecard, store()
ecwShareSuccess an eCard is successfully sent/shared form_data, share_mode, ecomm_*, ecard

ecwShareSuccess — react to a send/share #

Fires after a successful send (email, social, link, download…). Place this on the page with the widget:

document.addEventListener('ecwShareSuccess', function (e) {
  console.log('Shared:', e.detail);
  // e.detail.share_mode, e.detail.form_data, e.detail.ecomm_total, ...
});

e.detail contents:

Field Description
share_mode How it was shared: email, facebook, twitter, linkedin, sms, whatsapp, ecard_viewprint, ecard_download
form_data The full form: recipients (array of {name, email, type}), sender ({name, email}), personalMessage, plus settings like getReadReceipt, optedIn, setSchedule
ecomm_total Transaction value (for paid/donation widgets)
ecomm_currency Currency code (defaults to USD)
ecomm_testmode true when the widget is in test mode
ecard The selected eCard (id, widget id, owner, price, image, page title, config…)

Examples #

Google Analytics / GA4 — track a donation purchase

document.addEventListener('ecwShareSuccess', function (e) {
  gtag('event', 'purchase', {
    value: e.detail.ecomm_total,
    currency: e.detail.ecomm_currency
  });
});

Show a thank-you only for email sends

document.addEventListener('ecwShareSuccess', function (e) {
  if (e.detail.share_mode === 'email') {
    window.location.href = '/thank-you';
  }
});

Track social shares

document.addEventListener('ecwShareSuccess', function (e) {
  if (['facebook', 'twitter', 'linkedin'].includes(e.detail.share_mode)) {
    console.log('Shared on social:', e.detail.share_mode);
  }
});

ecwWidgetLoaded — initialize / customize on load #

Fires ~once when the widget is ready. e.detail.store() returns the widget's live state store, which you can read and adjust for advanced customization.

document.addEventListener('ecwWidgetLoaded', function (e) {
  window.ecwStore = e.detail.store();
  console.log(window.ecwStore.state);

  // e.g. default the opt-in checkbox to checked
  window.ecwStore.state.form.optedIn = true;
  window.ecwStore.state.shareForm.optedIn = true;
});

Scope to a specific widget with the vanity-id variant (handy when multiple widgets are on a page):

document.addEventListener('ecwWidgetLoaded_w6v62rn95yq', function (e) {
  const store = e.detail.store();
  // ...customize only this widget
});

Example: donation-based send limit #

Cap how many eCards a visitor can send in a session based on, say, their donation amount:

document.addEventListener('ecwWidgetLoaded', function (e) {
  const store = e.detail.store();
  const donationAmount = 5;
  store.state.wconfig.limitEmailsPerSession = donationAmount;
});

ecwOpenEcardForm — when the form opens #

Fires when the send form opens (typically right after the visitor picks an eCard). e.detail gives you both ecard (the selected eCard the visitor is about to send) and store() (same live state store as above) — useful for last-moment tweaks before the form is shown.

document.addEventListener('ecwOpenEcardForm', function (e) {
  console.log('Opening form for eCard:', e.detail.ecard);
  const store = e.detail.store();
  store.state.form.optedIn = true;
});

Custom merge tags — attach your own data to every send #

Besides listening to events, your page can hand the widget extra key/value data that is saved with each eCard a visitor sends and is available as merge tags: write [key] anywhere in the eCard's subject, header or body text (eCards → Details) and it is replaced with the value at send time. Typical uses: the campaign or page the card was sent from, a product or membership id, a referral code, an order number.

Set window.ecw_merge_tags, keyed by the widget's container id — the id of the <div> in your embed code, e.g. ecardwidget_id_12345. Each value is a plain string:

<script>
  window.ecw_merge_tags = window.ecw_merge_tags || {};
  window.ecw_merge_tags['ecardwidget_id_12345'] = {
    campaign: 'spring-appeal-2026',
    page_url: window.location.href,
    member_id: 'M-88412'
  };
</script>
<script type="text/javascript" src="https://app.ecardwidget.com/embed/widget/12345"></script>
<div id="ecardwidget_id_12345"></div>

Then in the eCard's body text: Thank you for supporting our [campaign] appeal.

How it behaves

  • The widget reads the object when the visitor submits the send form, so you can set or change it at any time before that: before the embed script loads, inside an ecwWidgetLoaded or ecwOpenEcardForm handler, or after your own page logic runs.
  • Keys are case-sensitive and must match the [key] you type into the eCard exactly; stick to letters, numbers and underscores. A [key] with no value supplied is left as typed.
  • Values are stored with the send, replaced into the card's text, and included in the merge_tags field of the ecard_shared webhook, so your own systems see them too.
  • Your values are merged after the sender's custom-field answers, so a key that matches a custom field's name overrides what the sender typed. Avoid the built-in names recipient_name, sender_name, sender_email, personal_message and donation_amount.
  • Several widgets on one page each get their own entry, keyed by their container id.

Shopify product pages add their own product merge tags; see Shopify.


Notes #

  • These events require the widget to be embedded on your page (they fire in the browser).
  • Reading/adjusting store().state is advanced — log it first to discover what's safe to change; the shape can evolve.
  • For server-to-server notifications (e.g. logging every send to your backend), use the ecard_shared webhook instead — it doesn't depend on the browser.

Documentation