Developer Documentation · v1.0

Widget API für SupportTheWork.

Erweitere das eingebettete widget.js per JavaScript-Hooks, DOM-Events und CSS-Overrides. Diese Referenz dokumentiert jeden Lifecycle-Hook, jeden CSS-Selektor und jede Variable, die das Widget öffentlich macht.

Version
1.0.4
Bundle
~9.4 kB gzip
Globale
window.SupportTheWork
Event Prefix
stw:*
Stand
Mai 2026
01 - Schnellstart

Einbindung

Das Widget wird als asynchrones Script geladen. Es injiziert einen Floating-Button und ein Modal in deine Seite. Sonst gibt es keine globalen Nebenwirkungen.

html
<script
  src="https://supportthework.com/api/widget.js"
  data-key="DEIN_WIDGET_KEY"
  data-theme="auto"
  async
></script>
02 - Schnellstart

Konfiguration via data-*

Die meiste Konfiguration läuft über das Dashboard und wird beim Laden geholt. Drei Attribute kannst du aber im Script-Tag setzen.

AttributWerteBeschreibung
data-keystringDein Widget-Key aus dem Dashboard. Pflicht.
data-theme"auto" | "light" | "dark"Erscheinung. auto folgt prefers-color-scheme.
data-previewbooleanPreview-Modus: Keine echten Zahlungen, kein Backend-Call.
03 - API

JavaScript Hooks

Nach dem Laden stellt das Widget window.SupportTheWork bereit. Hooks kannst du vor oder nach dem Script-Tag registrieren - vorausgemeldete Hooks werden beim Bootstrap übernommen.

Vorab deklarieren

html
<script>
  window.SupportTheWork = window.SupportTheWork || {};
  window.SupportTheWork.hooks = {
    ready(detail) {
      console.log('Widget bereit', detail.projectId);
    },
    'amount:select'(detail) {
      console.log('Betrag gewählt:', detail.amount);
    },
    'checkout:start'(detail) {
      console.log('Checkout startet', detail);
    },
  };
</script>

<script src="https://supportthework.com/api/widget.js" data-key="DEIN_WIDGET_KEY" async></script>

Dynamisch registrieren

js
const unsubscribe = window.SupportTheWork.on('modal:open', (detail) => {
  console.log('Modal offen', detail);
});

// später:
unsubscribe();

Wildcard-Hook

js
window.SupportTheWork.on('*', (detail) => {
  console.log(detail.event, detail);
});
04 - API

DOM Events

Jeder Hook wird parallel als CustomEvent auf window ausgesendet. Der Eventname ist immer stw:<hook-name>. Damit kannst du das Widget ohne JavaScript-Globals beobachten - z. B. aus einem Framework heraus.

javascript
window.addEventListener('stw:checkout:start', (event) => {
  console.log(event.detail.amount);
});
i
Hook oder Event? Beide bekommen die gleiche detail-Payload. Verwende Hooks für eng gekoppelte Custom-Logik, DOM-Events für lose gekoppelte Beobachter wie Analytics oder Consent-Banner.
05 - API

Öffentliche Methoden

Vier Methoden zum direkten Steuern des Widgets von außen.

MethodeBeschreibung
SupportTheWork.open()Öffnet das Widget, wenn es geladen ist. Triggert modal:before-open und modal:open.
SupportTheWork.close()Schließt das Modal. Triggert modal:before-close und modal:close.
SupportTheWork.getState()Liefert den aktuellen Widget-Zustand synchron (siehe Event Payload).
SupportTheWork.versionProperty, kein Funktionsaufruf. Aktuelle Widget-Version als String.
06 - API

Event Payload

Jeder Hook und jedes DOM-Event bekommt ein detail-Objekt mit dem vollständigen Snapshot-Zustand des Widgets. Beträge sind immer in Cent (500 = 5,00 €).

ts
{
  version: string;
  widgetKey: string | null;
  projectId: string | null;
  project: {
    id: string;
    accentColor: string;
    accentColorLight: string;
    accentColorDark: string;
    buttonText: string;
    titleText: string;
    presetAmounts: number[];
    allowCustomAmount: boolean;
  } | null;
  preview: boolean;
  modalOpen: boolean;
  selectedAmount: number | null;
  // + event-spezifische Felder: amount, field, value, error, url
}
07 - API

Cancelbare Hooks

Drei Hooks lassen sich abbrechen: modal:before-open, modal:before-close und checkout:before. Gib aus dem Handler false zurück oder rufe event.preventDefault() auf.

javascript
window.SupportTheWork.on('checkout:before', (detail, event) => {
  if (!window.analyticsConsent) {
    event.preventDefault();
    return false;
  }
});
!
Cancelt nur einer von mehreren Handlern, wird der Vorgang abgebrochen - also Vorsicht mit kollidierenden Listenern. Nicht-cancelbare Hooks ignorieren preventDefault() stillschweigend.
08 - Referenz

Hook-Liste

Vollständige Liste aller Hooks, gruppiert nach Lifecycle-Phase. Tags markieren cancelbare Hooks.

HookTypWann
config:loadedLifecycleKonfiguration wurde vom Backend geladen.
readyLifecycleWidget ist gerendert und einsatzbereit.
unavailableLifecycleWidget bleibt unsichtbar, weil es nicht geladen werden konnte.
button:renderUIFloating-Button wurde in den DOM gemountet.
modal:before-openCancelbarVor dem Öffnen des Modals.
modal:openUIModal wurde geöffnet.
modal:before-closeCancelbarVor dem Schließen des Modals.
modal:closeUIModal wurde geschlossen.
amount:selectUIPreset-Betrag wurde gewählt. detail.amount in Cent.
field:changeUIFormularfeld wurde geändert. detail.field, detail.value.
validation:errorUILokale Validierung zeigt einen Fehler. detail.field, detail.error.
statusUIStatusmeldung wurde im Modal angezeigt.
checkout:beforeCancelbarNach Validierung, vor dem API-Request.
checkout:startFlowCheckout-Request startet.
checkout:redirectFlowStripe-URL wurde erhalten, Redirect folgt. detail.url.
checkout:errorFlowCheckout konnte nicht gestartet werden. detail.error.
return:showFlowSuccess/Cancel-Rückkehr-Modal wurde angezeigt.
09 - Styling

CSS Selektoren

Das Widget nutzt stabile IDs, Klassen und data-*-Attribute. Lade deine CSS-Datei nach dem Widget oder gib deinen Selektoren genug Spezifität, damit Overrides greifen.

Klassen

#stw-buttonFloating-Trigger
.stw-overlayBackdrop
.stw-panelModal-Container
.stw-headerModal-Kopf
.stw-logoProject-Mark
.stw-titleTitle-Text
.stw-descriptionSubtitle
.stw-bodyScroll-Body
.stw-amountPreset-Chip
.stw-amount.is-selectedAktiver Chip
.stw-custom-fieldCustom-Eingabe
.stw-fieldFormularfeld
.stw-submitSubmit-Button
.stw-footerModal-Fuß
.stw-brand"Powered by"

Data-Attribute

[data-stw="button"]= #stw-button
[data-stw="overlay"]= .stw-overlay
[data-stw="panel"]= .stw-panel
[data-stw="submit"]= .stw-submit
[data-stw-field="email"]E-Mail-Input
[data-stw-field="name"]Name-Input
10 - Styling

CSS Variablen

Subtle Overrides ohne hartes !important - überschreibe einfach die Custom Properties an .stw-panel bzw. #stw-button.

Panel-Variablen

VariableDefaultVerwendung
--stw-panel#ffffffModal-Hintergrund
--stw-text#242231Primärtext
--stw-text-2#5b5667Sekundärtext
--stw-text-3#7e7787Tertiärtext
--stw-text-4#a9a19bPlaceholder, Disabled
--stw-border#e6e0daInputs, Chips, Trennlinien
--stw-bg-sub#f7f5f2Subtile Hintergründe
--stw-bg-soft#efebe6Hover-States
--stw-accent#6366f1Akzent (Submit, Selected)
--stw-accent-strong#5658d4Akzent Hover
--stw-accent-softrgba(99,102,241,.1)Akzent-Tint

Button-Variablen

VariableDefaultVerwendung
--stw-button-bottom24pxAbstand vom unteren Rand des Viewports
--stw-button-right24pxAbstand vom rechten Rand des Viewports
11 - Styling

Beispiel: Custom Theme

Stark angepasstes Look-and-Feel - Pill-Buttons, große Radii, kräftige Schatten. Drop-in nach dem Widget-Script.

css
#stw-button {
  border-radius: 14px;
  padding-inline: 22px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.22);
}

.stw-panel {
  width: min(92vw, 460px);
  border-radius: 22px;
  border: 0;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.28);
}

.stw-amount {
  border-radius: 999px;
  height: 48px;
}

.stw-submit {
  height: 52px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
i
Falls ein Inline-Style aus dem Widget gewinnt - überschreibe ihn bewusst mit !important. Für normale Layout- und Design-Anpassungen reichen die Klassen und Variablen aber aus.