Formulir feedback untuk website atau aplikasi

Formulir feedback untuk website atau aplikasi5 menit baca

Jalankan survei NPS di situs Anda sendiri, dari tautan email hingga skor

Jalankan survei NPS dengan skor 0 sampai 10 di email, pertanyaan lanjutan di halaman Anda sendiri yang berubah sesuai skor, dan script yang menghitung NPS.

Preet SutharPendiri, Ikiform

Taruh sebelas tautan, 0 sampai 10, di email survei, masing-masing mengarah ke halaman di situs Anda dengan skor dan token responden yang tidak bisa ditebak di URL. Halaman memilih skor itu lebih dulu, mengajukan pertanyaan lanjutan sesuai skornya, dan tidak mencatat apa pun sampai orang itu menekan Kirim. Simpan skor di field number dari 0 sampai 10, lalu hitung NPS sebagai porsi skor 9 dan 10 dikurangi porsi skor 0 sampai 6.

Apa yang berbeda dari NPS

NPS mengajukan satu pertanyaan dengan skala tetap: seberapa besar kemungkinan Anda merekomendasikan kami, dari 0 sampai 10. Tiga detail membuatnya berbeda dari rating 1 sampai 5 di pilar:

  • Skalanya mulai dari 0. Field rating Ikiform berjalan dari 1 hingga maksimal 10, jadi tidak bisa menampung 0. NPS memakai field number dengan min: 0, max: 10, dan integer: true, disimpan sebagai angka.
  • Biasanya dikirim lewat email. Klien email tidak bisa diandalkan untuk mengirim formulir atau menjalankan script, jadi email membawa tautan, dan formulirnya ada di situs Anda. Ikiform tidak punya halaman formulir yang di-host.
  • Tautan di email diklik oleh mesin. Banyak pemindai keamanan email membuka setiap tautan dalam pesan untuk memeriksanya. Jika membuka tautan langsung mencatat skor, Anda akan mengumpulkan skor dari pemindai. Halaman hanya mencatat saat seseorang menekan Kirim.
Bagaimana setiap rentang skor NPS mendapat pertanyaan lanjutannya sendiri dan dihitung dalam hasil0 sampai 6Apa yang palingmengecewakan Anda?detractordikurangkan7 atau 8Apa yang akanmembuatnya jadi 10?passivehanya dihitung di total9 atau 10Apa yang palingAnda hargai?promoterditambahkanskorpertanyaan lanjutandihitung sebagaiBagaimana setiap rentang skor NPS mendapat pertanyaan lanjutannya sendiri dan dihitung dalam hasil0sampai6ApayangpalingmengecewakanAnda?detractordikurangkan7 atau8Apayangakanmembuatnyajadi10?passivehanyadihitungdi total9 atau10ApayangpalingAndahargai?promoterditambahkanskorpertanyaanlanjutandihitungsebagai
  1. Skor 0 sampai 6 menanyakan apa yang mengecewakan mereka, dan dihitung sebagai detractor.
  2. Skor 7 atau 8 menanyakan apa yang akan membuatnya menjadi 10, dan hanya dihitung dalam total.
  3. Skor 9 atau 10 menanyakan apa yang paling mereka hargai, dan dihitung sebagai promoter.
  4. NPS adalah persentase promoter dikurangi persentase detractor, dari minus 100 hingga 100.
Pertanyaannya berubah sesuai skor karena jawaban yang berguna juga berbeda. Alasan detractor adalah masalah yang perlu diperbaiki; alasan promoter adalah bahan copy untuk homepage Anda.

Field-nya

Pratinjau

Menjalankan validator Ikiform di browser Anda. Tidak ada yang dikirim.

Coba skor 11 atau 7.5: Ikiform menolak keduanya. wave yang tidak ada juga ditolak, jadi setiap jawaban termasuk dalam satu putaran survei.
FieldAlasan
scorenumber, 0 sampai 10, hanya bilangan bulat. Disimpan sebagai angka
reasonPertanyaan lanjutan. Opsional, karena skor saja tetap dihitung
respondentToken yang tidak bisa ditebak yang Anda buat per orang lalu kirim. Dipetakan kembali ke pelanggan di database Anda sendiri
wavePutaran yang mana, seperti 2026-q4. Memungkinkan Anda membandingkan kuartal tanpa filter tanggal

Jangan taruh email atau ID akun pelanggan di tautan. URL berakhir di riwayat browser, log proxy, dan email yang diteruskan. Token acak 16 karakter atau lebih memberi tahu Anda siapa yang menjawab dan tidak memberi tahu apa pun kepada orang lain.

Email survei

Susun deretan tautan dengan merge tag alat email Anda, atau buat di kode yang mengirim email. Fungsi ini mengembalikan HTML untuk satu responden:

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>`;
}

Batasi email pada pertanyaan dan deretan angka. Intro yang panjang mendorong skala ke bawah layar di ponsel, dan sebagian besar jawaban datang dari orang yang mengklik angka tanpa menggulir.

Landing page

Taruh ini di /nps di situs Anda. Halaman menggambar skala 0 sampai 10, memilih skor dari tautan, mengatur pertanyaan lanjutan untuk skor itu, dan mengirim dengan fetch hanya saat orang itu menekan Kirim. Jika mereka mengubah skor di halaman, pertanyaannya ikut berubah.

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>
Halaman ini juga bekerja tanpa tautan: seseorang yang membuka /nps langsung melihat skala tanpa pilihan. Jawaban mereka ditolak karena wave tidak ada, kecuali Anda mengatur nilai default, sehingga kunjungan nyasar tidak masuk ke angka Anda.

Hitung skornya

Baca setiap jawaban untuk satu gelombang dengan SDK, simpan jawaban terakhir per responden, dan terapkan rumusnya. Jalankan dengan secret key di IKIFORM_SECRET_KEY:

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}`);

Script menyimpan satu jawaban per responden karena orang kadang mengklik angka kedua setelah berubah pikiran. Ikiform tidak menggabungkan atau menolak kiriman berulang berdasarkan email. Pengulangan identik dalam 24 jam hanya menambah skor spam. Lakukan deduplikasi di tempat daftar itu disimpan, atau saat Anda mengekspor.

Pastikan berfungsi

  1. Buka /nps?score=3&r=test_respondent_0001&wave=2026-q4. Angka 3 terpilih dan pertanyaannya berbunyi "What disappointed you most?"
  2. Klik 9. Pertanyaannya berubah menjadi "What do you value most about it?"
  3. Buka tautan yang sama dengan curl. Tidak ada yang baru di Submissions, karena tidak ada yang dikirim.
  4. Tekan Kirim. Jawaban menampilkan score sebagai angka 9.
  5. Jalankan node nps.mjs 2026-q4. Hasilnya melaporkan satu orang dan satu promoter.

Hal yang sering menjebak

  • Jangan terlalu sering menyurvei pelanggan yang sama. Tentukan interval, misalnya sekali per kuartal, dan simpan daftar responden di sisi Anda.
  • Sampel kecil berayun liar. Dengan 20 jawaban, satu orang menggeser NPS sebesar 5 poin. Laporkan jumlah orang di samping skornya.
  • Skor rendah layak dibalas. Kirim detractor ke chat tim Anda dengan relay webhook seperti peringatan skor rendah di pilar, memakai score <= 6.
  • Template formulir survei menanyakan skor di dalam survei yang lebih panjang. Itu cocok untuk studi sekali jalan; pertanyaan NPS yang berdiri sendiri mendapat lebih banyak jawaban.
  • Ikiform tidak mengirim email ke orang yang mengisi formulir. Email notifikasi hanya dikirim ke Anda dan tim, jadi tidak ada autoresponder, email konfirmasi, atau double opt-in. Kirim semua itu dari alat email Anda, dipicu oleh webhook.

Pemecahan masalah

MasalahYang harus dilakukan
422 dengan Must be at most 10, atau error bilangan bulatSkornya berasal dari luar skala, misalnya URL yang diedit manual. Halaman hanya menerima 0 sampai 10 dari tautan; periksa tautan di template email Anda.
422 yang menyebut waveTautan tidak membawa wave, atau nilainya tidak cocok dengan format seperti 2026-q4. Perbaiki template email, atau atur nilai default di script halaman.
403 origin_not_allowed, atau setiap kiriman masuk ke spamDomain halaman tidak ada di Allowed domains formulir. Tambahkan, ditambah localhost untuk uji lokal. Subdomain dari domain yang terdaftar diizinkan.
429 rate_limitedSatu pengunjung mengirim melebihi rate limit formulir. Standard mengizinkan 5 per menit per pengunjung. Tunggu sesuai Retry-After, atau pilih Relaxed atau Custom untuk formulir yang mengirim dari satu IP bersama.

Pertanyaan

Mentok di salah satu langkah, atau ingin panduan untuk situasi Anda? Email hello@ikiform.com.