Feedback-Formular für eine Website oder App

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

Feature-Wünsche sammeln, die du zählen, gewichten und beantworten kannst

Ein Formular für Feature-Wünsche, das nach dem Problem statt nach der Lösung fragt, Wünsche nach Thema speichert, Personen statt Zeilen zählt und sie beim Release anschreibt.

Preet SutharGründer, Ikiform

Frag, was die Person erreichen will und wie sie es heute macht, nicht welches Feature sie möchte, und mach die E-Mail zur Pflicht, damit du ihr Bescheid geben kannst, wenn es erscheint. Speichere jeden Wunsch per Webhook in einer Tabelle, ordne Wünsche Themen zu und gewichte Themen danach, wie viele verschiedene Personen blockiert sind. Wenn ein Thema erscheint, schreib allen, die danach gefragt haben.

Was an Feature-Wünschen anders ist

Ein Bug-Report ist erledigt, wenn der Fehler behoben ist. Ein Feature-Wunsch ist ein Datenpunkt: einer von vielen Menschen, die dieselbe Lücke mit anderen Worten beschreiben. Daraus folgen drei Dinge:

  • Leute beschreiben Lösungen. „Fügt einen CSV-Button hinzu“ kann heißen „meine Steuerberaterin braucht die Rechnungen vom letzten Monat“. Frag nach der Aufgabe, dann kannst du eine bessere Lösung wählen als die gewünschte.
  • Derselbe Bedarf kommt viele Male an. Ikiform speichert jeden Post und führt Wiederholungen nicht zusammen, und zwei Leute benutzen ohnehin selten dieselben Worte. Du gruppierst Wünsche selbst nach Thema und zählst verschiedene Personen.
  • Der Wert liegt in der Rückmeldung. Jemandem zu sagen „du hast gefragt, wir haben es gebaut“ ist der beste Grund, überhaupt zu fragen. Dafür braucht jeder Wunsch eine E-Mail, deshalb ist sie in diesem Formular Pflicht.
Wie ein Feature-Wunsch zu einem gezählten Thema und einer Launch-E-Mail wirdWunschgesendetProblem,Bereich,Auswirkung,E-MailZeileindeinerTabellenachEinsendungs-IDpasstzueinemThema?duordnestwöchentlichzuThemenzähler+ 1verschiedenePersonen,BlockiertezuerstThemaerscheintallenschreiben,diegefragthabenneuesThemabeginntbeieinerPersonWebhookjaBuildneinWie ein Feature-Wunsch zu einem gezählten Thema und einer Launch-E-Mail wirdWunsch gesendetProblem, Bereich,Auswirkung, E-MailZeile in deinerTabellenach Einsendungs-IDpasst zueinem Thema?du ordnestwöchentlich zuThemenzähler + 1verschiedenePersonen, BlockiertezuerstThema erscheintallen schreiben, diegefragt habenneuesThemabeginnt beieiner PersonWebhookjaBuildnein
  1. Jemand beschreibt, was er erreichen will, wählt einen Bereich und eine Auswirkung und hinterlässt eine E-Mail.
  2. Ein Webhook-Relay fügt den Wunsch in deine Datenbank ein, einmal pro Einsendungs-ID.
  3. Jede Woche ordnest du neue Wünsche einem Thema zu, von Hand oder mit einem Muster.
  4. Passt er zu einem bestehenden Thema, steht hinter diesem Thema jetzt eine Person mehr.
  5. Wenn nicht, beginnt er ein neues Thema.
  6. Wenn ein Thema erscheint, wählst du jede E-Mail darin aus und schickst eine Nachricht.
Die Rangfolge sind Personen pro Thema, nicht rohe Wünsche. Ein Kunde, der fünfmal fragt, ist immer noch ein Kunde.

Nach dem Problem fragen

Vorschau

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

Wie wichtig ist es?

Wir schreiben dir, wenn es erscheint, oder wenn wir eine Frage haben.

problem hat ein Minimum von 30 Zeichen, was aus „dark mode pls“ einen Satz mit einer Begründung macht.
FeldWarum es da ist
problemDie Aufgabe, in ihren eigenen Worten. Mit Abstand das nützlichste Feld
workaroundZeigt dir, wie schmerzhaft es ist. „Ich kopiere es von Hand in eine Tabelle“ ist ein starkes Signal
areaEine grobe erste Sortierung, damit du innerhalb der Abrechnung zuordnest, nicht über alles hinweg
impactTrennt blockierte Kunden von neugierigen, formuliert als Ergebnisse, die Leute beurteilen können
emailPflicht. Ohne sie kannst du keine Rückmeldung geben und keine Frage stellen

Lass ein Prioritäts- oder Abstimmungsfeld weg. Jeder markiert seinen eigenen Wunsch als hohe Priorität, und die Zahl der Personen pro Thema ist eine bessere Abstimmung als jeder Button.

Das Formular

Das Formular braucht kein Skript: Es sendet und leitet weiter. Setze Redirect after submit auf eine Seite, die sagt, was als Nächstes passiert. Für eine Version, die in deinem Framework auf der Seite bleibt, nimm den Formularcode der Hauptanleitung und setze diese Felder ein.

feature-request.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label for="problem">What are you trying to do?</label>
  <textarea id="problem" name="problem" rows="5" required minlength="30"
    placeholder="Send last month's invoices to our accountant in one go"></textarea>
  <label for="workaround">How do you do it today?</label>
  <textarea id="workaround" name="workaround" rows="3"></textarea>
  <label for="area">Which part of the product?</label>
  <select id="area" name="area" required>
    <option value="billing">Billing and invoices</option>
    <option value="reports">Reports</option>
    <option value="team">Team and permissions</option>
    <option value="integrations">Integrations and API</option>
    <option value="other">Something else</option>
  </select>
  <fieldset>
    <legend>How much does it matter?</legend>
    <label><input type="radio" name="impact" value="blocking" required /> It stops us using the product for something</label>
    <label><input type="radio" name="impact" value="slow" /> It costs us time every week</label>
    <label><input type="radio" name="impact" value="nice" /> It would be nice</label>
  </fieldset>
  <label for="email">Email</label>
  <input id="email" name="email" type="email" required />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send request</button>
</form>

Wünsche per Webhook speichern

Dashboard und CSV-Export reichen für die ersten paar Dutzend Wünsche. Sobald du jede Woche Themen zuordnest und Personen zählst, ist eine Tabelle einfacher. Leg eine in Postgres an:

schema.sql
create table feature_requests (
  submission_id text primary key,
  area text not null,
  impact text not null,
  problem text not null,
  workaround text,
  email text not null,
  theme text,
  created_at timestamptz not null
);

Füge dann in Ikiform einen Webhook-Endpunkt hinzu, der auf diese Route zeigt. Sie läuft auf jedem Node-Host mit dem Paket pg, und dein eigener Server behandelt dasselbe Muster ausführlicher:

app/api/feature-requests/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { Pool } from "pg";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

const INSERT = `insert into feature_requests (submission_id, area, impact, problem, workaround, email, created_at)
values ($1, $2, $3, $4, $5, lower($6), $7)
on conflict (submission_id) do nothing`;

export async function POST(request: Request) {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({
      payload,
      headers: request.headers,
      secret: process.env.IKIFORM_WEBHOOK_SECRET!,
    });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
  if (event.type !== "submission.created") return new Response(null, { status: 204 });

  const { problem, workaround, area, impact, email } = event.data.fields;
  await pool.query(INSERT, [
    event.data.submission_id,
    area,
    impact,
    problem,
    workaround ?? null,
    email,
    event.data.created_at,
  ]);
  return new Response(null, { status: 204 });
}
  • verifyWebhook lehnt alles ab, was nicht mit dem whsec_-Secret deines Endpunkts signiert ist.
  • on conflict (submission_id) do nothing macht Wiederholungen sicher. Ikiform sendet eine fehlgeschlagene Zustellung mit derselben Einsendung erneut, und das zweite Insert bewirkt nichts.
  • Ein Datenbankfehler wirft eine Exception, die Route antwortet mit 500, und Ikiform versucht es später erneut. Bei einem Neustart der Datenbank gehen dir keine Wünsche verloren.
  • Die E-Mail wird beim Eintreffen in Kleinbuchstaben umgewandelt, damit das Zählen verschiedener Personen funktioniert.
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.

Zuordnen und gewichten

Neue Wünsche zuordnen

Lies einmal pro Woche die Zeilen ohne Thema und gib jeder eins. Muster erledigen die offensichtlichen; den Rest liest du selbst, denn die interessanten Wünsche passen zu keinem Muster.

tag.sql
update feature_requests
set theme = 'invoice-export'
where theme is null
  and area = 'billing'
  and problem ilike any (array['%export%', '%accountant%', '%download%']);

Themen gewichten

Das hier ordnet Themen danach, wie viele Wünsche angeben, blockiert zu sein, und dann danach, wie viele verschiedene Personen gefragt haben:

ranking.sql
select coalesce(theme, 'untagged') as theme,
       count(*) as requests,
       count(distinct email) as people,
       count(*) filter (where impact = 'blocking') as blocking
from feature_requests
group by 1
order by blocking desc, people desc;
  1. Lies die problem-Texte der drei wichtigsten Themen vollständig, bevor du irgendetwas entwirfst.
  2. Sieh dir die Workarounds an. Oft beseitigt eine kleine Änderung das Schlimmste.
  3. Wäge die Rangfolge gegen deinen Plan ab; sie zeigt Nachfrage, nicht, was richtig zu bauen ist.

Rückmeldung geben

Wenn ein Thema erscheint, hol dir alle, die danach gefragt haben:

notify.sql
select distinct email
from feature_requests
where theme = 'invoice-export';

Schick eine kurze E-Mail aus deinem E-Mail-Tool oder deinem eigenen Posteingang, die sagt, was erschienen ist, und darauf verlinkt. Ikiform schreibt 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. Verschick diese aus deinem E-Mail-Tool, ausgelöst durch einen Webhook. Dasselbe gilt hier: Die Launch-E-Mail kommt von dir, nicht von Ikiform.

Prüfen, ob es funktioniert

  1. Sende einen Wunsch mit einem Problem von 10 Zeichen. Ikiform antwortet mit 422 und nennt problem.
  2. Sende einen echten Wunsch. Er erscheint unter Submissions und als Zeile in feature_requests.
  3. Sende die Zustellung unter Webhooks erneut. Die Tabelle hat für diese Einsendung weiterhin eine Zeile.
  4. Sende zweimal mit derselben E-Mail in unterschiedlicher Schreibweise. Die Rangfolge-Abfrage zählt eine Person.

Stolperfallen

  • Ein öffentliches Feedback-Board wie Canny bietet Abstimmungen und eine öffentliche Statusseite. Sollen Kunden die Wünsche der anderen sehen, ist das das bessere Tool; dieses Setup hält Wünsche privat.
  • Wünsche mit mehreren Links können als Spam gewertet werden. Prüf den Filter Spam wöchentlich, solange das Aufkommen gering ist.
  • Fügst du später eine Option für area hinzu, ergänze sie zuerst in der Definition. Ein nicht gelisteter Wert wird abgelehnt.
  • Speichere, was du brauchst, und nicht mehr. Eine Tabelle mit Wünschen und E-Mails enthält personenbezogene Daten; nenne das in deiner Datenschutzerklärung und lösche Zeilen, die du nicht mehr brauchst.

Fehlerbehebung

ProblemWas zu tun ist
Zeilen fehlen in der TabelleÖffne den Endpunkt unter Webhooks. Ein 400 bedeutet, dass das Secret falsch ist; ein 500 mit einem Datenbankfehler bedeutet, dass das Insert fehlgeschlagen ist und Ikiform es erneut versucht.
422 validation_failedDer Post passt nicht zur Felddefinition des Formulars. error.fields nennt jedes Feld und den Grund. Gleiche den name des Eingabefelds an die Feld-ID an.
Die Einsendung ist im Dashboard, aber keine E-Mail und kein Webhook kam anSie wurde als Spam gespeichert. Spam löst nichts aus. Öffne sie unter dem Filter Spam, um die Gründe zu sehen, und markiere sie als kein Spam, um ihre E-Mail und Webhooks zu senden.

Fragen

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