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.
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
ratingvon Ikiform reicht von 1 bis höchstens 10, kann also keine 0 aufnehmen. NPS nutzt einnumber-Feld mitmin: 0,max: 10undinteger: 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.
- Ein Wert von 0 bis 6 fragt, was enttäuscht hat, und zählt als Kritiker.
- Eine 7 oder 8 fragt, was daraus eine 10 machen würde, und zählt nur zur Gesamtzahl.
- Eine 9 oder 10 fragt, was die Person am meisten schätzt, und zählt als Promoter.
- NPS ist der Prozentsatz der Promoter minus der Prozentsatz der Kritiker, von minus 100 bis 100.
Die Felder
Vorschau
Führt den Validator von Ikiform in deinem Browser aus. Es wird nichts gesendet.
wave wird abgelehnt, sodass jede Antwort zu einer Umfragerunde gehört.| Feld | Warum |
|---|---|
score | number, 0 bis 10, nur ganze Zahlen. Als Zahl gespeichert |
reason | Die Folgefrage. Optional, weil ein Wert allein auch zählt |
respondent | Ein undurchsichtiges Token, das du pro Person erzeugst und verschickst. Lässt sich in deiner eigenen Datenbank dem Kunden zuordnen |
wave | Welche 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:
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.
<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>/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:
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
- Öffne
/nps?score=3&r=test_respondent_0001&wave=2026-q4. Die 3 ist ausgewählt, und die Frage lautet „What disappointed you most?“ - Klick auf 9. Die Frage ändert sich zu „What do you value most about it?“
- Öffne denselben Link mit
curl. Unter Submissions erscheint nichts Neues, weil nichts gesendet wurde. - Drück auf Senden. Die Antwort zeigt
scoreals die Zahl 9. - Führe
node nps.mjs 2026-q4aus. 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
| Problem | Was zu tun ist |
|---|---|
422 mit Must be at most 10 oder einem Fehler zu ganzen Zahlen | Der 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 wave | Der 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 Spam | Die 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_limited | Ein 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
Setze elf Links von 0 bis 10 in die E-Mail, die jeweils eine Seite deiner Site mit dem Wert in der URL öffnen. Die Seite wählt ihn vor, stellt eine Folgefrage und speichert die Antwort, wenn die Person auf Senden drückt.
Nein. Ein rating reicht von 1 bis höchstens 10, und NPS braucht die 0. Nutze ein number-Feld mit min 0, max 10 und integer true.
Nimm den Prozentsatz der Antworten mit 9 oder 10, zieh den Prozentsatz mit 0 bis 6 ab und ignoriere 7 und 8 außer in der Gesamtzahl. Das Ergebnis reicht von minus 100 bis 100.
Sicherheitsscanner für E-Mails öffnen Links in eingehenden E-Mails, um sie zu prüfen. Beim Klick zu speichern würde diese Besuche als Antworten zählen. Erst beim Senden zu speichern, hält die Zahlen ehrlich.
Hängst du bei einem Schritt fest oder willst eine Anleitung für deinen Fall? Schreib an hello@ikiform.com.