⌘I

Formulare mit JavaScript (AJAX) absenden

Updated March 23, 2026 ·
howtoform-setup

Verfügbar in: Alle Tarife

Du kannst @formspree/ajax verwenden, um deine Formspree-Formulare mit reinem JavaScript abzusenden, ohne eine eigene fetch-, Axios- oder jQuery-Übermittlungslogik schreiben zu müssen.

Die Bibliothek funktioniert mit standardmäßigen HTML-Formularen und fügt über Datenattribute oder eine kleine JavaScript-API eine deklarative Formularverarbeitung hinzu. Sie kümmert sich automatisch um die Formularübermittlung, den Ladezustand, Validierungsfehler und Erfolgsmeldungen.

So funktioniert es

@formspree/ajax bietet dir eine deklarative Möglichkeit, ein Formular zu verkabeln. Anstatt manuell auf Submit-Events zu lauschen und deine eigene Request-Verarbeitung zu schreiben, versiehst du dein Formular mit Datenattributen und initialisierst es mit deiner Formspree-Formular-ID.

Standardmäßig kümmert sich die Bibliothek um:

  • die Formularübermittlung
  • den Ladezustand des Absende-Buttons
  • Validierungsfehler auf Feldebene
  • Fehler auf Formularebene
  • Erfolgsmeldungen
  • den Zustand ungültiger Felder mit aria-invalid="true"

So implementierst du es in deinem Projekt:

Schritt 1: @formspree-ajax in deinem Projekt einrichten

Du kannst @formspree/ajax auf zwei Arten verwenden, je nach deinem Setup:

  • Mit einem Bundler (ESM über npm/yarn)
  • Ohne Bundler (Script-Tag/CDN)

Option 1: Mit einem Bundler (ESM)

Installiere die Bibliothek:

npm install @formspree/ajax   # via npm, or
yarn add @formspree/ajax      # via yarn

Und initialisiere dein Formular in JavaScript:

import { initForm } from '@formspree/ajax';

initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',
});

Stelle sicher, dass die ID deines HTML-Formularelements mit der ID übereinstimmt, die du an die formElement-Eigenschaft übergibst. Und ersetze YOUR_FORM_ID durch die Formular-ID, die du im Formspree-Dashboard erhältst.

Option 2: Mit einem Script-Tag (kein Build-Schritt)

Wenn du keinen Bundler verwendest, füge dieses Snippet vor dem schließenden </body>-Tag ein:

<script>
  window.formspree =
    window.formspree ||
    function () {
      (formspree.q = formspree.q || []).push(arguments);
    };
  formspree(
    'initForm', 
    { formElement: '#contact-form', formId: 'YOUR_FORM_ID' }
  );
</script>
<script src="https://unpkg.com/@formspree/ajax@1" defer></script>

Ähnlich wie bei der ersten Option stelle sicher, dass die ID deines HTML-Formularelements mit der ID übereinstimmt, die du an die formElement-Eigenschaft übergibst. Und ersetze YOUR_FORM_ID durch die Formular-ID, die du im Formspree-Dashboard erhältst.

Schritt 2: Dein Formular erstellen

Sobald du @formspree/ajax in deinem Projekt eingerichtet hast, kannst du so ein Formular damit erstellen:

<div data-fs-success></div>
<div data-fs-error></div>

<form id="contact-form">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" data-fs-field />
  <span data-fs-error="email"></span>

  <button type="submit" data-fs-submit-btn>Send</button>
</form>

Stelle erneut sicher, dass der Wert im id-Attribut deines Formulars mit der ID übereinstimmt, die du im vorherigen Schritt als formId im initForm-Aufruf übergeben hast.

Die Bibliothek übermittelt das Formular automatisch an Formspree, deaktiviert den Absende-Button, während die Anfrage läuft, zeigt Validierungsfehler an und zeigt eine Erfolgsmeldung an.

Datenattribute

Die @formspree-ajax-Bibliothek liefert einige Attribute mit, mit denen du steuern kannst, wie sich das Formular verhält, ohne zusätzliches JavaScript zu benötigen.

data-fs-error="fieldName"

Verwende dies an einem <span> oder <div>, um Validierungsfehler auf Feldebene anzuzeigen.

<span data-fs-error="email"></span>

Wenn das Element leer ist, fügt Formspree die API-Fehlermeldung ein. Wenn das Element bereits Inhalt enthält, wird dieser Inhalt stattdessen ein- oder ausgeblendet.

data-fs-error

Verwende dies ohne Wert, um Fehler auf Formularebene anzuzeigen.

<div data-fs-error></div>

Dies ist nützlich für allgemeine Übermittlungsfehler, die nicht zu einem bestimmten Feld gehören.

data-fs-success

Verwende dies, um nach der Übermittlung eine Erfolgsmeldung anzuzeigen.

<div data-fs-success></div>

Wenn das Element leer ist, wird die Standardmeldung angezeigt. Wenn es bereits Inhalt hat, wird dieser Inhalt stattdessen verwendet.

data-fs-field

Verwende dies an Formularfeldern, die aria-invalid="true" erhalten sollen, wenn die Validierung fehlschlägt.

<input type="email" name="email" data-fs-field />

Die Bibliothek liest den Feldnamen aus dem name-Attribut des Elements.

data-fs-submit-btn

Verwende dies am Absende-Button, damit er während der Übermittlung deaktiviert und danach wieder aktiviert wird.

<button type="submit" data-fs-submit-btn>Send</button>

Standardverhalten

Wenn du nichts überschreibst, bietet die Bibliothek sinnvolle Standardwerte:

  • Der Absende-Button ist deaktiviert, während das Formular übermittelt wird.
  • Feldfehler werden in passenden data-fs-error="fieldName"-Elementen angezeigt.
  • Ungültige Felder erhalten aria-invalid="true".
  • Eine Erfolgsmeldung wird im data-fs-success-Element angezeigt.
  • Eine Fehlermeldung auf Formularebene wird im data-fs-error-Element angezeigt.
  • Wenn es kein data-fs-success-Element und keinen benutzerdefinierten onSuccess-Handler gibt, wird das Formular durch eine „Thank you!”-Meldung ersetzt.
  • Wenn es ein data-fs-success-Element und keinen benutzerdefinierten onSuccess-Handler gibt, wird das Formular nach einer erfolgreichen Übermittlung zurückgesetzt.
  • Grundlegende Standard-Styles werden automatisch eingefügt.

Erweiterte Konfiguration

Die Bibliothek bietet außerdem Möglichkeiten, das Verhalten und das Aussehen deines Formulars weiter anzupassen.

Zusätzliche Daten zu jeder Übermittlung hinzufügen

Du kannst die data-Option verwenden, um jeder Formularübermittlung zusätzliche Werte anzuhängen. Die Werte können sein:

  • statische Zeichenketten
  • synchrone Funktionen
  • asynchrone Funktionen

Alle undefined-Werte werden übersprungen. So verwendest du es:

initForm({
  formElement: '#my-form',
  formId: 'YOUR_FORM_ID',

  // This data will be added to every submission
  data: {
    source: 'landing-page',
    referrer: () => document.referrer || undefined,
    sessionId: async () => await fetchSessionId(),
  },
});

Es ist nützlich, um Metadaten wie Kampagnennamen, Empfehlungsquellen oder Session-IDs anzuhängen, ohne versteckte Inputs zu deinem HTML hinzuzufügen.

Lifecycle-Callbacks

Du kannst dich in verschiedene Phasen des Übermittlungs-Lifecycles einklinken.

initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',

  // Called when the form is initialized
  onInit: (context) => {
    console.log('Form initialized');
  },

  // Called before submission is sent.
  onSubmit: (context) => {
    console.log('Submitting form');
  },

  // Called on successful submission.
  onSuccess: (context, result) => {
    console.log('Submission succeeded', result);
  },

  // Called if validation errors are received from Formspree
  onError: (context, error) => {
    console.log('Validation error', error);
  },

  // Called if unexpected errors are received (e.g., network failure).
  onFailure: (context, error) => {
    console.log('Unexpected error', error);
  },
});

Das context-Objekt enthält das aktuelle Formular (HTMLFormElement), die Endpoint-Details, den Client und das Konfigurationsobjekt, das du an initForm übergeben hast.

Diese Callbacks können verwendet werden für:

  • das Tracken von Events (Analytics, Conversions, Abbrüche)
  • das Anzeigen benutzerdefinierter UI (Spinner, Toasts, Banner)
  • die Weiterleitung nach erfolgreicher Übermittlung
  • das Loggen oder Debuggen von Requests und Fehlern
  • die benutzerdefinierte Behandlung von Validierungs- oder Formularfehlern
  • das Ausführen von Seiteneffekten vor oder nach der Übermittlung (z. B. das Speichern von Zuständen, das Auslösen von Workflows)

Benutzerdefiniertes Rendering

Du kannst das Standard-UI-Verhalten überschreiben, indem du benutzerdefinierte Rendering-Methoden in initForm() bereitstellst. Das ist nützlich, wenn du die volle Kontrolle darüber haben möchtest, wie Ladezustände, Fehler und Erfolgsmeldungen erscheinen.

initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',

  enable: (context) => {},
  disable: (context) => {},
  renderFieldErrors: (context, error) => {},
  renderSuccess: (context, message) => {},
  renderFormError: (context, message) => {},
});

Verfügbare Methoden

MethodeWann sie ausgeführt wirdHäufige Verwendungen
disable(context)Wenn die Übermittlung startetLadezustand hinzufügen, Buttons/Inputs deaktivieren
enable(context)Nachdem die Übermittlung abgeschlossen istSpinner entfernen, UI wieder aktivieren
renderFieldErrors(context, error)Bei ValidierungsfehlernBenutzerdefinierte Fehler-UI, gruppierte Fehler, Toast-Meldungen
renderSuccess(context, message)Bei erfolgreicher ÜbermittlungFormular ersetzen, Toast anzeigen, weiterleiten
renderFormError(context, message)Bei Fehlern auf FormularebeneFehlerbanner, Alerts, zentralisierte Meldungen

So verwendest du sie:

initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',

  disable: ({ form }) => form.classList.add('loading'),
  enable: ({ form }) => form.classList.remove('loading'),

  renderSuccess: ({ form }, message) => {
    form.innerHTML = `<p>${message}</p>`;
  },
});

Styling

Die Bibliothek enthält Standard-Styles für Fehler, ungültige Felder und Erfolgsmeldungen. Du kannst sie mit deinem eigenen CSS überschreiben.

[data-fs-error] {
  color: #dc3455;
}

[data-fs-field][aria-invalid='true'] {
  border-color: #dc3455;
}

[data-fs-success][data-fs-active] {
  background: #de4dda;
}

[data-fs-error=''][data-fs-active] {
  background: #f87dda;
  color: #72c124;
}

Aufräumen

initForm() gibt ein Handle mit einer destroy()-Methode zurück. Du kannst dies verwenden, wenn du das Formularverhalten später bereinigen musst.

const handle = initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',
});

// Clean up when needed
handle.destroy();

Vollständiges ESM-Beispiel

Hier ist ein vollständiges Beispiel mit einem reinen HTML-Formular und @formspree/ajax mit einem Bundler. Initialisiere zunächst das Formular mit deiner Formspree-Formular-ID:

import { initForm } from '@formspree/ajax';

initForm({
  formElement: '#contact-form',
  formId: 'YOUR_FORM_ID',
});

Erstelle dann das HTML-Formular mit den oben beschriebenen Datenattributen:

<div data-fs-success></div>
<div data-fs-error></div>

<form id="contact-form">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" data-fs-field />
  <span data-fs-error="email"></span>

  <label for="message">Message</label>
  <textarea id="message" name="message" data-fs-field></textarea>
  <span data-fs-error="message"></span>

  <button type="submit" data-fs-submit-btn>Send</button>
</form>

Script-Tag-Beispiel

Wenn du die Bibliothek ohne Build-Schritt verwenden möchtest, kannst du sie direkt im Browser initialisieren:

<div data-fs-success></div>
<div data-fs-error></div>

<form id="my-form">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" data-fs-field />
  <span data-fs-error="email"></span>

  <label for="message">Message</label>
  <textarea id="message" name="message" data-fs-field></textarea>
  <span data-fs-error="message"></span>

  <button type="submit" data-fs-submit-btn>Submit</button>
</form>

<script>
  window.formspree =
    window.formspree ||
    function () {
      (formspree.q = formspree.q || []).push(arguments);
    };

  formspree('initForm', {
    formElement: '#my-form',
    formId: 'YOUR_FORM_ID',
  });
</script>
<script src="https://unpkg.com/@formspree/ajax@1" defer></script>

Migration von manuellem AJAX-Code

Wenn du Formulare zuvor mit benutzerdefiniertem fetch-, Axios- oder jQuery-Code übermittelt hast, bietet dir @formspree/ajax eine einfachere Alternative. Anstatt manuell:

  • auf Submit-Events zu lauschen
  • Formulardaten zu serialisieren
  • Requests zu senden
  • Validierungsfehler zu parsen
  • das DOM für Erfolgs- und Fehlerzustände zu aktualisieren

kannst du die Bibliothek einmal initialisieren und sie diese Teile für dich erledigen lassen.

Hinweis zu Frameworks

Diese Bibliothek ist für reines JavaScript und standardmäßige HTML-Formulare konzipiert. Wenn du React verwendest, sieh dir stattdessen unsere React-Bibliothek an.