# Kumpulkan permintaan fitur yang bisa Anda hitung, urutkan, dan tanggapi

> Formulir permintaan fitur yang menanyakan masalahnya alih-alih solusinya, menyimpan permintaan per tema, menghitung orang bukan baris, dan mengirim email saat fiturnya rilis.

Terbit 2026-10-25 · https://ikiform.com/id/guides/feedback-form/feature-request

Tanyakan apa yang ingin dilakukan orang itu dan bagaimana mereka melakukannya sekarang, bukan fitur apa yang mereka inginkan, dan wajibkan email agar Anda bisa memberi tahu saat fiturnya rilis. Simpan setiap permintaan di tabel lewat webhook, beri tag tema, dan urutkan tema berdasarkan berapa banyak orang berbeda yang terhambat. Saat sebuah tema rilis, kirim email ke semua yang memintanya.

## Apa yang berbeda dari permintaan fitur

Laporan bug selesai saat diperbaiki. Permintaan fitur adalah titik data: satu dari banyak orang yang menggambarkan celah yang sama dengan kata-kata berbeda. Ada tiga konsekuensinya:

- **Orang menggambarkan solusi.** "Tambahkan tombol CSV" mungkin berarti "akuntan saya butuh invoice bulan lalu". Tanyakan tugasnya, dan Anda bisa memilih perbaikan yang lebih baik dari yang diminta.
- **Kebutuhan yang sama datang berkali-kali.** Ikiform menyimpan setiap kiriman dan tidak menggabungkan pengulangan, dan dua orang jarang memakai kata yang sama. Anda sendiri yang mengelompokkan permintaan per tema dan menghitung orang yang berbeda.
- **Nilainya ada di tindak lanjut.** Memberi tahu seseorang "Anda meminta, kami membangunnya" adalah alasan terbaik untuk bertanya. Itu butuh email di setiap permintaan, jadi formulir ini mewajibkannya.

Diagram: Cara permintaan fitur menjadi tema yang dihitung dan email peluncuran

1. Seseorang menjelaskan apa yang ingin dilakukannya, memilih area dan dampak, lalu meninggalkan email.
2. Relay webhook memasukkan permintaan ke database Anda, sekali per ID kiriman.
3. Setiap minggu Anda memberi tag tema pada permintaan baru, secara manual atau dengan pola.
4. Jika cocok dengan tema yang ada, tema itu kini punya satu orang lagi di belakangnya.
5. Jika tidak, permintaan itu memulai tema baru.
6. Saat sebuah tema rilis, Anda memilih setiap email di dalamnya dan mengirim satu pesan.

Peringkatnya adalah jumlah orang per tema, bukan jumlah permintaan mentah. Satu pelanggan yang meminta lima kali tetap satu pelanggan.

## Tanyakan masalahnya

Formulir: Feature request

- **Apa yang ingin Anda lakukan?** (`problem`, textarea, wajib)
- **Bagaimana Anda melakukannya sekarang?** (`workaround`, textarea)
- **Bagian produk yang mana?** (`area`, select, wajib)
- **Seberapa penting hal ini?** (`impact`, radio, wajib)
- **Email** (`email`, email, wajib)

`problem` punya minimum 30 karakter, yang mengubah "dark mode dong" menjadi kalimat yang berisi alasan.

| Field | Alasan ada di sini |
| --- | --- |
| `problem` | Tugas yang ingin dicapai, dengan kata-kata mereka. Sejauh ini field paling berguna |
| `workaround` | Menunjukkan seberapa menyakitkan masalahnya. "Saya menyalinnya ke spreadsheet secara manual" adalah sinyal kuat |
| `area` | Pemilahan awal yang kasar, jadi Anda memberi tag di dalam penagihan, bukan di semua hal |
| `impact` | Memisahkan pelanggan yang terhambat dari yang sekadar penasaran, ditulis sebagai dampak yang bisa dinilai orang |
| `email` | Wajib. Tanpanya Anda tidak bisa menindaklanjuti atau mengajukan pertanyaan |

Jangan sertakan field prioritas atau voting. Semua orang menandai permintaannya sendiri sebagai prioritas tinggi, dan jumlah orang per tema adalah voting yang lebih baik daripada tombol apa pun.

## Formulirnya

Formulir ini tidak butuh script: ia mengirim lalu me-redirect. Atur **Redirect after submit** ke halaman yang menjelaskan apa yang terjadi selanjutnya. Untuk versi yang tetap di halaman dalam framework Anda, ambil [kode formulir](https://ikiform.com/id/guides/feedback-form.md#form) dari pilar dan ganti dengan field-field ini.

`feature-request.html`:

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

## Simpan permintaan lewat webhook

Dashboard dan ekspor CSV cukup untuk beberapa puluh permintaan pertama. Begitu Anda memberi tag tema dan menghitung orang setiap minggu, tabel lebih mudah. Buat satu di Postgres:

`schema.sql`:

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

Lalu tambahkan endpoint [webhook](https://ikiform.com/id/docs/webhooks.md) di Ikiform yang mengarah ke route ini. Route ini berjalan di host Node mana pun dengan paket `pg`, dan [server Anda sendiri](https://ikiform.com/blog/form-submissions-to-your-own-server.md) membahas pola yang sama lebih dalam:

`app/api/feature-requests/route.ts`:

```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` menolak apa pun yang tidak ditandatangani dengan secret `whsec_` endpoint Anda.
- `on conflict (submission_id) do nothing` membuat percobaan ulang aman. Ikiform mengirim ulang pengiriman yang gagal dengan kiriman yang sama, dan insert kedua tidak berpengaruh apa-apa.
- Error database akan melempar exception, route menjawab `500`, dan Ikiform mencoba ulang nanti. Anda tidak kehilangan permintaan saat database di-restart.
- Email diubah menjadi huruf kecil saat masuk, sehingga penghitungan orang yang berbeda berfungsi.

> 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.

## Beri tag dan urutkan

### Beri tag permintaan baru

Seminggu sekali, baca baris yang belum diberi tag dan beri masing-masing sebuah tema. Pola menangani yang jelas; baca sisanya sendiri, karena permintaan yang menarik tidak cocok dengan pola.

`tag.sql`:

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

### Urutkan tema

Query ini mengurutkan tema berdasarkan berapa banyak permintaan yang menyatakan terhambat, lalu berdasarkan berapa banyak orang berbeda yang meminta:

`ranking.sql`:

```text
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. Baca teks `problem` dari tiga tema teratas secara lengkap sebelum Anda mendesain apa pun.
2. Perhatikan cara-cara yang dipakai untuk mengakalinya. Sering kali satu perubahan kecil menghilangkan bagian terburuknya.
3. Timbang peringkat itu dengan rencana Anda; peringkat menunjukkan permintaan, bukan apa yang tepat untuk dibangun.

## Tindak lanjuti

Saat sebuah tema rilis, ambil semua orang yang memintanya:

`notify.sql`:

```text
select distinct email
from feature_requests
where theme = 'invoice-export';
```

Kirim satu email singkat dari alat email Anda atau inbox Anda sendiri, sebutkan apa yang rilis dan sertakan tautannya. Ikiform tidak mengirim email ke orang yang mengisi formulir. Email notifikasi hanya dikirim ke Anda dan tim Anda, jadi tidak ada autoresponder, email konfirmasi, atau double opt-in. Kirim semua itu dari alat email Anda, dipicu oleh [webhook](https://ikiform.com/id/docs/webhooks.md). Hal yang sama berlaku di sini: email peluncuran datang dari Anda, bukan dari Ikiform.

## Pastikan berfungsi

1. Kirim permintaan dengan masalah sepanjang 10 karakter. Ikiform menjawab `422` dengan menyebut `problem`.
2. Kirim permintaan sungguhan. Permintaan itu muncul di **Submissions** dan sebagai baris di `feature_requests`.
3. Di **Webhooks**, kirim ulang pengirimannya. Tabel tetap punya satu baris untuk kiriman itu.
4. Kirim dua kali dengan email yang sama dalam huruf besar-kecil berbeda. Query peringkat menghitungnya sebagai satu orang.

## Hal yang sering menjebak

- Papan feedback publik, seperti Canny, menambahkan voting dan halaman status publik. Jika Anda ingin pelanggan melihat permintaan satu sama lain, itu alat yang lebih baik; penyiapan ini menjaga permintaan tetap privat.
- Permintaan yang berisi beberapa tautan bisa dinilai sebagai spam. Periksa filter **Spam** setiap minggu selama volumenya masih rendah.
- Jika nanti Anda menambahkan opsi `area`, tambahkan ke definisi terlebih dahulu. Nilai yang tidak terdaftar akan ditolak.
- Simpan yang Anda butuhkan dan tidak lebih. Tabel permintaan berisi email adalah data pribadi; sebutkan di pemberitahuan privasi Anda dan hapus baris yang tidak lagi Anda butuhkan.

## Pemecahan masalah

| Masalah | Yang harus dilakukan |
| --- | --- |
| Baris tidak muncul di tabel | Buka endpoint di **Webhooks**. `400` berarti secret-nya salah; `500` dengan error database berarti insert gagal dan Ikiform sedang mencoba ulang. |
| `422 validation_failed` | Kiriman tidak cocok dengan definisi field formulir. `error.fields` menyebutkan setiap field dan alasannya. Samakan `name` input dengan ID field. |
| Kiriman ada di dashboard tetapi tidak ada email atau webhook yang datang | Kiriman itu disimpan sebagai spam. Spam tidak mengirim apa pun. Buka di filter **Spam** untuk melihat alasannya, dan tandai sebagai bukan spam untuk mengirim email dan webhook-nya. |

## Pertanyaan

### Apa yang sebaiknya ditanyakan formulir permintaan fitur?

Apa yang ingin dilakukan orang itu, bagaimana mereka melakukannya sekarang, bagian produk mana yang terkait, seberapa penting hal itu, dan email. Menanyakan masalahnya alih-alih fiturnya memberi Anda ruang untuk menemukan perbaikan yang lebih baik.

### Bagaimana cara menangani permintaan fitur yang duplikat?

Anggap itu wajar dan hitung orangnya, bukan barisnya. Beri tag tema pada setiap permintaan dan urutkan tema berdasarkan email yang berbeda. Ikiform menyimpan setiap kiriman dan tidak menggabungkan pengulangan.

### Bisakah pengguna memberi voting pada permintaan fitur?

Tidak dengan formulir saja. Formulir menjaga permintaan tetap privat; papan publik seperti Canny menambahkan voting. Menghitung orang berbeda per tema memberi Anda padanan yang privat.

### Bagaimana cara memberi tahu orang saat permintaan mereka rilis?

Simpan email bersama setiap permintaan, pilih setiap email di tema yang sudah rilis, dan kirim satu pesan dari alat email Anda. Ikiform sendiri tidak mengirim email ke pengirim formulir.

## Panduan lainnya

- [Formulir feedback untuk website atau aplikasi](https://ikiform.com/id/guides/feedback-form.md): Pasang formulir feedback di halaman mana pun atau di dalam aplikasi Anda: rating, komentar, halaman asalnya, filter spam, dan peringatan saat skornya rendah.
- [Formulir laporan bug](https://ikiform.com/id/guides/feedback-form/bug-report.md): Formulir laporan bug yang menanyakan langkah dan tingkat keparahan, dan membiarkan halaman menambahkan URL, browser, viewport, dan error terbaru dengan sendirinya.
- [Feedback beta tester](https://ikiform.com/id/guides/feedback-form/beta-tester-feedback.md): Formulir feedback beta dengan tautan pribadi per tester dan build, dua skala rating, dan ringkasan mingguan yang menunjukkan apakah setiap build makin baik.
- [Survei NPS](https://ikiform.com/id/guides/feedback-form/nps-survey.md): 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.
- [Widget feedback React](https://ikiform.com/id/guides/feedback-form/react-feedback-widget.md): Tombol feedback mengambang untuk aplikasi React yang membuka panel kecil, mengirim layar, versi aplikasi, dan akun bersama setiap jawaban, dan tidak pernah kehilangan draf.
- [Survei pembatalan](https://ikiform.com/id/guides/feedback-form/cancellation-survey.md): Tanyakan mengapa pelanggan membatalkan di dalam alur pembatalan SaaS Anda, jaga Skip tetap satu klik, simpan alasannya ke Stripe dan Ikiform, dan jangan pernah menunda pembatalan.
