Feedback-Formular für eine Website oder App

Feedback-Formular für eine Website oder App6 Min. Lesezeit

NPS-Umfrage auf deiner eigenen Site durchführen, vom E-Mail-Link bis zum Wert

Führe eine NPS-Umfrage mit einem Wert von 0 bis 10 in der E-Mail durch, mit einer Folgefrage auf deiner eigenen Seite, die sich mit dem Wert ändert, und einem Skript, das den NPS berechnet.

Preet SutharGründer, Ikiform

Setze elf Links von 0 bis 10 in die Umfrage-E-Mail, die jeweils mit dem Wert und einem undurchsichtigen Teilnehmer-Token in der URL auf eine Seite deiner Site zeigen. Die Seite wählt den Wert vor, stellt eine davon abhängige Folgefrage und speichert nichts, bis die Person auf Senden drückt. Speichere den Wert in einem number-Feld von 0 bis 10 und berechne den NPS als Anteil der 9er und 10er minus den Anteil von 0 bis 6.

Was am NPS anders ist

NPS stellt eine Frage mit fester Skala: Wie wahrscheinlich empfiehlst du uns weiter, von 0 bis 10. Drei Details unterscheiden ihn von der Bewertung von 1 bis 5 in der Hauptanleitung:

  • Die Skala beginnt bei 0. Das Feld rating von Ikiform reicht von 1 bis höchstens 10, kann also keine 0 aufnehmen. NPS nutzt ein number-Feld mit min: 0, max: 10 und integer: true, gespeichert als Zahl.
  • Er wird meist per E-Mail verschickt. E-Mail-Clients senden Formulare nicht zuverlässig ab und führen keine Skripte aus, also enthält die E-Mail Links, und das Formular liegt auf deiner Site. Ikiform hat keine gehosteten Formularseiten.
  • Links in E-Mails werden von Maschinen angeklickt. Viele Sicherheitsscanner für E-Mails öffnen jeden Link einer Nachricht, um ihn zu prüfen. Würde das Öffnen eines Links einen Wert speichern, würdest du Werte von Scannern sammeln. Die Seite speichert erst, wenn eine Person auf Senden drückt.
Wie jeder NPS-Wertebereich seine eigene Folgefrage bekommt und ins Ergebnis einfließt0 bis 6Was hat dich ammeisten enttäuscht?Kritikerabgezogen7 oder 8Was würde darauseine 10 machen?Passivernur in der Gesamtzahlgezählt9 oder 10Was schätzt du ammeisten?PromoteraddiertbewertenFolgefragezählt alsWie jeder NPS-Wertebereich seine eigene Folgefrage bekommt und ins Ergebnis einfließt0 bis 6Was hatdich ammeistenenttäuscht?Kritikerabgezogen7 oder8Waswürdedarauseine 10machen?Passivernur inderGesamtzahlgezählt9 oder10Wasschätztdu ammeisten?PromoteraddiertbewertenFolgefragezählt als
  1. Ein Wert von 0 bis 6 fragt, was enttäuscht hat, und zählt als Kritiker.
  2. Eine 7 oder 8 fragt, was daraus eine 10 machen würde, und zählt nur zur Gesamtzahl.
  3. Eine 9 oder 10 fragt, was die Person am meisten schätzt, und zählt als Promoter.
  4. NPS ist der Prozentsatz der Promoter minus der Prozentsatz der Kritiker, von minus 100 bis 100.
Die Frage ändert sich mit dem Wert, weil sich die nützliche Antwort ändert. Der Grund eines Kritikers ist ein Problem, das du beheben musst; der eines Promoters ist Text für deine Startseite.

Die Felder

Vorschau

Führt den Validator von Ikiform in deinem Browser aus. Es wird nichts gesendet.

Probier einen Wert von 11 oder 7.5: Ikiform lehnt beide ab. Auch ein fehlendes wave wird abgelehnt, sodass jede Antwort zu einer Umfragerunde gehört.
FeldWarum
scorenumber, 0 bis 10, nur ganze Zahlen. Als Zahl gespeichert
reasonDie Folgefrage. Optional, weil ein Wert allein auch zählt
respondentEin undurchsichtiges Token, das du pro Person erzeugst und verschickst. Lässt sich in deiner eigenen Datenbank dem Kunden zuordnen
waveWelche Runde, etwa 2026-q4. Damit vergleichst du Quartale ohne Datumsfilter

Setze weder die E-Mail noch die Konto-ID des Kunden in den Link. URLs landen im Browserverlauf, in Proxy-Logs und in weitergeleiteten E-Mails. Ein zufälliges Token mit 16 oder mehr Zeichen sagt dir, wer geantwortet hat, und allen anderen nichts.

Die Umfrage-E-Mail

Baue die Linkreihe mit den Merge-Tags deines E-Mail-Tools oder erzeuge sie im Code, der die E-Mail verschickt. Diese Funktion gibt das HTML für einen Teilnehmer zurück:

nps-email.js
function npsRow(respondent, wave) {
  const cells = Array.from({ length: 11 }, (_, score) => {
    const link = new URL("https://example.com/nps");
    link.searchParams.set("score", String(score));
    link.searchParams.set("r", respondent);
    link.searchParams.set("wave", wave);
    return `<td><a href="${link}" style="display:block;padding:8px 10px">${score}</a></td>`;
  });
  return `<table role="presentation"><tr>${cells.join("")}</tr></table>
<p>0 is not at all likely, 10 is extremely likely.</p>`;
}

Beschränke die E-Mail auf die Frage und die Zahlenreihe. Eine lange Einleitung schiebt die Skala auf Smartphones aus dem sichtbaren Bereich, und die meisten Antworten kommen von Leuten, die ohne zu scrollen eine Zahl anklicken.

Die Landingpage

Setze das unter /nps auf deine Site. Die Seite zeichnet die Skala von 0 bis 10, wählt den Wert aus dem Link vor, setzt die Folgefrage für diesen Wert und sendet erst per fetch, wenn die Person auf Senden drückt. Ändert sie den Wert auf der Seite, ändert sich die Frage mit.

nps.html
<form id="nps" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <fieldset>
    <legend>How likely are you to recommend us to a friend or colleague?</legend>
    <div id="nps-scale"></div>
  </fieldset>
  <label for="reason" id="reason-label">What's the main reason for your score?</label>
  <textarea id="reason" name="reason" rows="4" maxlength="4000"></textarea>
  <input type="hidden" name="respondent" />
  <input type="hidden" name="wave" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send</button>
  <p id="nps-status" role="status"></p>
</form>

<script>
  const QUESTIONS = [
    [6, "What disappointed you most?"],
    [8, "What would make it a 10 for you?"],
    [10, "What do you value most about it?"],
  ];
  const params = new URLSearchParams(location.search);
  const form = document.getElementById("nps");
  const label = document.getElementById("reason-label");
  const scale = document.getElementById("nps-scale");

  for (let score = 0; score <= 10; score += 1) {
    scale.insertAdjacentHTML(
      "beforeend",
      `<label><input type="radio" name="score" value="${score}" required /> ${score}</label>`,
    );
  }

  function askFor(score) {
    label.textContent = QUESTIONS.find(([top]) => score <= top)[1];
  }

  const preset = Number(params.get("score"));
  if (params.has("score") && Number.isInteger(preset) && preset >= 0 && preset <= 10) {
    form.elements.score.value = String(preset);
    askFor(preset);
  }
  form.elements.respondent.value = params.get("r") ?? "";
  form.elements.wave.value = params.get("wave") ?? "";
  scale.addEventListener("change", (event) => askFor(Number(event.target.value)));

  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    const status = document.getElementById("nps-status");
    status.textContent = "Sending";
    const response = await fetch(form.action, {
      method: "POST",
      headers: { Accept: "application/json" },
      body: new FormData(form),
    }).catch(() => null);
    const result = await response?.json().catch(() => null);
    if (result?.ok) {
      form.replaceChildren(Object.assign(document.createElement("p"), { textContent: "Thanks for answering." }));
      return;
    }
    status.textContent = result?.error?.fields?.score?.[0] ?? result?.error?.message ?? "Couldn't send it. Try again.";
  });
</script>
Die Seite funktioniert auch ohne Link: Wer /nps direkt öffnet, sieht die Skala ohne Auswahl. Seine Antwort wird wegen eines fehlenden wave abgelehnt, außer du setzt einen Standardwert, was zufällige Besuche aus deinen Zahlen heraushält.

Den Wert berechnen

Lies mit dem SDK jede Antwort einer Runde, behalte pro Teilnehmer die neueste Antwort und wende die Formel an. Führe es mit einem Secret Key in IKIFORM_SECRET_KEY aus:

nps.mjs
import { createClient } from "@ikiform/sdk";

const WAVE = process.argv[2] ?? "2026-q4";
const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY });
const latest = new Map();

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx", status: "received" })) {
  const { score, respondent, wave } = submission.fields;
  if (wave !== WAVE) continue;
  const key = respondent || submission.id;
  const seen = latest.get(key);
  if (!seen || seen.at < submission.created_at) latest.set(key, { score, at: submission.created_at });
}

const scores = [...latest.values()].map((answer) => answer.score);
const promoters = scores.filter((value) => value >= 9).length;
const detractors = scores.filter((value) => value <= 6).length;
const nps = Math.round(((promoters - detractors) / scores.length) * 100);

console.log(`${WAVE}: ${scores.length} people, ${promoters} promoters, ${detractors} detractors, NPS ${nps}`);

Das Skript behält eine Antwort pro Teilnehmer, weil Leute manchmal eine zweite Zahl anklicken, nachdem sie es sich anders überlegt haben. Ikiform führt wiederholte Einsendungen nicht nach E-Mail zusammen und lehnt sie nicht ab. Eine identische Wiederholung innerhalb von 24 Stunden erhöht nur den Spam-Score. Entferne Duplikate dort, wo die Liste liegt, oder beim Export.

Prüfen, ob es funktioniert

  1. Öffne /nps?score=3&r=test_respondent_0001&wave=2026-q4. Die 3 ist ausgewählt, und die Frage lautet „What disappointed you most?“
  2. Klick auf 9. Die Frage ändert sich zu „What do you value most about it?“
  3. Öffne denselben Link mit curl. Unter Submissions erscheint nichts Neues, weil nichts gesendet wurde.
  4. Drück auf Senden. Die Antwort zeigt score als die Zahl 9.
  5. Führe node nps.mjs 2026-q4 aus. Es meldet eine Person und einen Promoter.

Stolperfallen

  • Befrage denselben Kunden nicht zu oft. Wähle ein Intervall, etwa einmal pro Quartal, und führe die Teilnehmerliste auf deiner Seite.
  • Kleine Stichproben schwanken stark. Bei 20 Antworten verschiebt eine Person den NPS um 5 Punkte. Nenne neben dem Wert die Zahl der Personen.
  • Niedrige Werte verdienen eine Antwort. Schick Kritiker mit einem Webhook-Relay wie dem Alert für niedrige Bewertungen der Hauptanleitung in deinen Team-Chat, mit score <= 6.
  • Die Umfrage-Vorlage fragt den Wert innerhalb einer längeren Umfrage ab. Das passt zu einer einmaligen Studie; eine eigenständige NPS-Frage bekommt mehr Antworten.
  • Ikiform schickt der Person, die das Formular ausfüllt, keine E-Mail. Benachrichtigungs-E-Mails gehen nur an dich und dein Team, es gibt also keinen Autoresponder, keine Bestätigungs-E-Mail und kein Double-Opt-in. Verschicke sie aus deinem E-Mail-Tool, ausgelöst durch einen Webhook.

Fehlerbehebung

ProblemWas zu tun ist
422 mit Must be at most 10 oder einem Fehler zu ganzen ZahlenDer Wert kam nicht von der Skala, etwa aus einer von Hand bearbeiteten URL. Die Seite akzeptiert aus dem Link nur 0 bis 10; prüf die Links in deiner E-Mail-Vorlage.
422 mit Nennung von waveDer Link enthielt kein wave, oder der Wert passt nicht zum Format 2026-q4. Korrigiere die E-Mail-Vorlage oder setze einen Standardwert im Skript der Seite.
403 origin_not_allowed, oder jeder Post landet im SpamDie Domain der Seite steht nicht unter Allowed domains des Formulars. Füge sie hinzu, plus localhost für lokale Tests. Subdomains einer eingetragenen Domain sind erlaubt.
429 rate_limitedEin Besucher hat mehr gesendet, als das Rate-Limit des Formulars erlaubt. Standard erlaubt 5 pro Minute und Besucher. Warte Retry-After ab oder wähle Relaxed oder Custom für Formulare, die von einer gemeinsamen IP aus senden.

Fragen

Hängst du bei einem Schritt fest oder willst eine Anleitung für deinen Fall? Schreib an hello@ikiform.com.