Formulir feedback untuk website atau aplikasi

Formulir feedback untuk website atau aplikasi5 menit baca

Tambahkan formulir laporan bug yang mencatat halaman, browser, dan langkah-langkahnya

Formulir laporan bug yang menanyakan langkah dan tingkat keparahan, dan membiarkan halaman menambahkan URL, browser, viewport, dan error terbaru dengan sendirinya.

Preet SutharPendiri, Ikiform

Tanyakan pelapor hanya hal yang mereka ketahui: apa yang salah, apa yang mereka lakukan sebelumnya, dan seberapa besar hal itu menghambat mereka. Biarkan halaman mengisi sisanya saat submit: URL halaman, user agent browser, viewport, dan beberapa error JavaScript terakhir. Kirim ke backend formulir dan teruskan setiap laporan ke issue tracker Anda lewat webhook.

Apa yang berbeda dari laporan bug

Laporan bug hanya berguna jika Anda bisa mereproduksinya, dan pelapor jarang tahu detail yang Anda butuhkan. Tanyakan browser yang mereka pakai dan Anda akan mendapat "Chrome" atau "yang biasa". Minta URL-nya dan Anda mendapat nama halamannya. Jadi bagi formulirnya menjadi dua: pertanyaan yang hanya bisa dijawab pelapor, dan konteks yang sudah diketahui halaman.

Bagian laporan bug yang diketik orang dan yang ditambahkan halamandiketik pelaporditambahkan halaman saat submitringkasansatu baris, 8sampai 140karakterlangkahyang dilakukantepatsebelumnyakeparahanblocker, majoratau minortautanscreenshotopsional, URLbukan filepage_urlorigin danpath, tanpaqueryuser_agentbrowser dan OSviewportukuran danrasio pikselrecent_errorslima terakhir,host dihapusBagian laporan bug yang diketik orang dan yang ditambahkan halamandiketik pelaporditambahkan halaman saat submitringkasansatu baris, 8 sampai 140karakterlangkahyang dilakukan tepat sebelumnyakeparahanblocker, major atau minortautan screenshotopsional, URL bukan filepage_urlorigin dan path, tanpa queryuser_agentbrowser dan OSviewportukuran dan rasio pikselrecent_errorslima terakhir, host dihapus
  1. Pelapor menulis ringkasan satu baris.
  2. Mereka menjelaskan apa yang mereka lakukan tepat sebelum terjadi kerusakan.
  3. Mereka memilih seberapa parah hal itu menghambat mereka.
  4. Mereka bisa menempel tautan ke screenshot atau rekaman.
  5. Saat submit, halaman menambahkan alamatnya sendiri tanpa query string.
  6. Halaman menambahkan user agent browser.
  7. Halaman menambahkan ukuran jendela dan rasio piksel.
  8. Halaman menambahkan beberapa error JavaScript terakhir yang dilihatnya, dengan hostname dihapus.
Baris atas adalah satu-satunya yang dilihat pelapor. Baris bawah adalah input tersembunyi, yang diisi saat mereka menekan Kirim.

Tiga batasan membentuk kodenya:

  • Referrer bukan halamannya. Secara default browser hanya mengirim origin Anda pada kiriman lintas situs, jadi meta.referrer tidak akan memberi tahu path-nya. Kirim page_url sendiri.
  • Kiriman dari server menyembunyikan browser. Ikiform mencatat user agent dari siapa pun yang membuat request. Dari server action, itu adalah server Anda. Teruskan header user-agent pengunjung sebagai field.
  • Stack trace penuh dengan tautan. Setiap frame memiliki URL script, dan tiga tautan atau lebih menambah 2 pada skor spam. Hapus host sebelum Anda mengirim error, atau laporan dengan tautan screenshot yang ditempel bisa tergelincir menjadi spam.

Field-nya

Pratinjau

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

Seberapa besar hal ini menghambat Anda?
Lima field terakhir adalah input tersembunyi di formulir sebenarnya. Setelah didefinisikan, Ikiform memeriksa panjang dan tipenya seperti field lainnya.

Tingkat keparahan ditulis sebagai dampaknya bagi pelapor, bukan sebagai label prioritas. Orang memilih "Saya tidak bisa melanjutkan" dengan akurat; mereka memilih "Kritis" untuk segalanya. Langkah punya minimum 20 karakter, yang mengubah "rusak" menjadi kalimat yang bisa Anda tindak lanjuti.

Tangkap konteksnya

Browser mengisi field tersembunyi di handler submit, setelah orang selesai mengetik, sehingga daftar error mencakup apa pun yang salah selama mereka menulis laporan.

Formulir mengirim dengan cara biasa; script hanya mengisi input tersembunyi saat submit, sebelum browser menyusun request. Atur data-app-version di elemen <html> saat build. Browser mengirim langsung, jadi meta.user_agent milik Ikiform sama dengan field user_agent.

report-bug.html
<form id="bug" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <label for="summary">What went wrong?</label>
  <input id="summary" name="summary" required minlength="8" maxlength="140" />
  <label for="steps">What did you do right before?</label>
  <textarea id="steps" name="steps" rows="5" required minlength="20"></textarea>
  <label for="expected">What did you expect to happen?</label>
  <textarea id="expected" name="expected" rows="3"></textarea>
  <fieldset>
    <legend>How much does it block you?</legend>
    <label><input type="radio" name="severity" value="blocker" required /> I can't continue</label>
    <label><input type="radio" name="severity" value="major" /> I found a workaround</label>
    <label><input type="radio" name="severity" value="minor" /> It's cosmetic</label>
  </fieldset>
  <label for="screenshot_url">Link to a screenshot or recording</label>
  <input id="screenshot_url" name="screenshot_url" type="url" />
  <label for="email">Email for follow-up questions</label>
  <input id="email" name="email" type="email" />
  <input type="hidden" name="page_url" />
  <input type="hidden" name="user_agent" />
  <input type="hidden" name="viewport" />
  <input type="hidden" name="app_version" />
  <input type="hidden" name="recent_errors" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send report</button>
</form>

<script>
  const recent = [];
  function remember(text) {
    recent.push(String(text).replace(/https?:\/\/[^/\s]+/g, "").slice(0, 400));
    if (recent.length > 5) recent.shift();
  }
  window.addEventListener("error", (event) => remember(`${event.message} at ${event.filename}:${event.lineno}`));
  window.addEventListener("unhandledrejection", (event) => remember(`Unhandled: ${event.reason?.stack ?? event.reason}`));

  document.getElementById("bug").addEventListener("submit", (event) => {
    const fields = event.currentTarget.elements;
    fields.page_url.value = location.origin + location.pathname;
    fields.user_agent.value = navigator.userAgent;
    fields.viewport.value = `${innerWidth}x${innerHeight} @${devicePixelRatio}x`;
    fields.app_version.value = document.documentElement.dataset.appVersion ?? "";
    fields.recent_errors.value = recent.join("\n---\n");
  });
</script>
Versi sisi server mengirim dengan secret key, sehingga Ikiform melewati Allowed domains dan pemeriksaan manusianya. Semua kiriman lalu datang dari IP server Anda, dan batas Standard 5 per menit per pengunjung menghitung semua pengunjung Anda sebagai satu. Pilih rate limit Relaxed atau Custom untuk formulir yang Anda kirim lewat server, dan simpan IKIFORM_SECRET_KEY di environment variable khusus server.

Pesan sukses menampilkan ID kiriman. Saat pelapor menghubungi support nanti, ID itu menemukan laporannya dalam satu pencarian. Template laporan bug punya versi lebih pendek tanpa konteks yang ditangkap.

Masuk ke issue tracker Anda

Laporan sebaiknya berada di tempat perbaikannya dilacak. Tambahkan webhook yang mengarah ke relay yang membuat issue: summary sebagai judul, langkah dan konteks sebagai isi, severity sebagai label. Panduan Linear dan GitHub Issues punya relay tersebut, lengkap dengan pemeriksaan tanda tangan dan percobaan ulang. Dokumentasi webhook mendaftar setiap nilai meta yang dibawa payload. Taruh field yang ditangkap di blok yang diciutkan di akhir isi issue agar langkah-langkahnya tetap mudah dibaca.

FieldDi issue
summaryJudul
steps, expectedIsi, paling awal
severityLabel, agar blocker bisa difilter
page_url, user_agent, viewport, app_versionBlok details di bawah langkah-langkah
recent_errorsBlok kode, paling akhir

Pastikan berfungsi

  1. Buka halaman di browser desktop, jalankan undefinedFunction() di konsol, lalu kirim laporan.
  2. Buka kiriman di dashboard. recent_errors berisi ReferenceError tanpa host https:// di dalamnya.
  3. user_agent menampilkan browser Anda, bukan node, juga di versi server.
  4. page_url berisi path tetapi tanpa query string.
  5. Kirim laporan dengan steps sepanjang 10 karakter. Ikiform menjawab 422 dengan menyebut steps, dan formulir menampilkan pesannya.

Hal yang sering menjebak

  • Unggah file belum didukung. Kiriman berisi file mendapat 422 files_not_supported. Mintalah tautan ke screenshot, atau unggah gambar ke storage Anda sendiri terlebih dahulu lalu kirim URL-nya.
  • Setiap nilai bisa sampai 16 KB. Lima error yang dipotong menjadi 400 karakter masih jauh di bawah itu; dump konsol lengkap tidak.
  • Browser Chromium membekukan sebagian string user agent, seperti versi macOS, yang selalu terbaca 10_15_7. Gunakan nama browser dan versi mayornya, bukan versi OS, saat melakukan triase.
  • Error dari script di origin lain hanya menampilkan Script error. kecuali script itu disajikan dengan header CORS dan dimuat dengan crossorigin.
  • Jangan menangkap isi formulir, local storage, atau cookie ke dalam laporan. Isinya bisa berupa password dan token, dan Anda akan menyimpannya dalam teks biasa.

Pemecahan masalah

MasalahYang harus dilakukan
422 validation_failedKiriman tidak cocok dengan definisi field formulir. error.fields menyebutkan setiap field dan alasannya. Samakan name input dengan ID field.
422 files_not_supportedFormulir punya <input type="file"> dengan file yang dipilih. Upload file belum didukung; hapus input itu atau minta link sebagai gantinya.
Laporan dengan tautan screenshot masuk ke spamHitung tautan di semua field. Tiga atau lebih menambah skor; ditambah pengulangan laporan yang sama, skornya mencapai ambang batas. Hapus host dari error dan tandai laporan sebagai bukan spam.
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.

Pertanyaan

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