> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useshareable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Collect feedback on options

> Send reviewers a page of options, let them pick, and get every pick back in one table.

Goal: you have a few versions of something (email drafts, taglines, designs) and want people to
tell you **which one they'd send**, and why. They open one link, pick, and press **Send**. You
get one table with every reviewer's picks, which you can split into one row per question.

This replaces the old way of doing it, where the page downloads a JSON file and the reviewer
has to email it back to you.

<Steps>
  <Step title="Have your AI build the picker">
    Ask Claude, ChatGPT, or Gemini:

    > *"Build a page that shows these 3 groups of email drafts. For each group, let the
    > reader pick the one they'd send and say why. Add a Send button that submits the picks
    > to Shareable with `Shareable.submit`, with one entry per group in a `rows` list. If
    > `window.Shareable` isn't there, download the picks as JSON instead."*

    Or start from the example below.
  </Step>

  <Step title="Publish and share">
    Publish the page on Shareable. Because the page calls `Shareable.submit`, it starts
    [collecting responses](/guides/collect-responses) automatically. Pick who can open it in
    **Share**. Use **verified email** or **specific people** if you want each response labelled
    with the reviewer's email.
  </Step>

  <Step title="Read the picks">
    Open the page in your dashboard and click **Responses**. Split the table on **`rows`** to get
    one row per reviewer per group, with the reviewer's name copied onto each row, then
    download a CSV. Or ask your agent to *"summarize the responses on my picker page"* (it uses
    `get_responses`).
  </Step>
</Steps>

## The example page

```html theme={null}
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Which version would you send?</title>
  <style>
    body { font: 16px/1.5 system-ui, sans-serif; max-width: 720px; margin: 40px auto; padding: 0 16px; }
    fieldset { border: 1px solid #ddd; border-radius: 10px; margin: 0 0 20px; padding: 16px; }
    label.opt { display: block; padding: 8px; border-radius: 8px; cursor: pointer; }
    label.opt:hover { background: #f4f4f8; }
    textarea { width: 100%; margin-top: 8px; }
  </style>
</head>
<body>
  <h1>Which version would you send?</h1>
  <p><label>Your name <input id="reader" required></label></p>

  <div id="groups"></div>
  <button id="send">Send my picks</button>
  <p id="status"></p>

  <script>
    const GROUPS = [
      { id: 'welcome', options: { A: 'Welcome aboard! Here’s how to get started…', B: 'Hi! Glad you’re here. Three things to try first…' } },
      { id: 'renewal', options: { A: 'Your plan renews on Friday.', B: 'Heads up: your plan renews in 3 days.' } },
    ]

    const root = document.getElementById('groups')
    for (const g of GROUPS) {
      const fs = document.createElement('fieldset')
      fs.innerHTML = `<legend>${g.id}</legend>` +
        Object.entries(g.options).map(([k, text]) =>
          `<label class="opt"><input type="radio" name="${g.id}" value="${k}"> <b>${k}</b> — ${text}</label>`
        ).join('') +
        `<label class="opt"><input type="radio" name="${g.id}" value="none"> None of these</label>` +
        `<textarea id="why-${g.id}" placeholder="Why?"></textarea>`
      root.append(fs)
    }

    document.getElementById('send').onclick = async () => {
      const data = {
        reader: document.getElementById('reader').value,
        rows: GROUPS.map(g => ({
          group: g.id,
          best: document.querySelector(`input[name="${g.id}"]:checked`)?.value ?? null,
          why: document.getElementById(`why-${g.id}`).value,
        })),
      }

      const status = document.getElementById('status')
      const res = window.Shareable ? await Shareable.submit(data) : { ok: false }
      if (res.ok) {
        status.textContent = res.updated ? 'Updated ✓ (your new picks replaced the old ones)' : 'Sent ✓ Thank you!'
      } else {
        if (res.error) status.textContent = res.error
        // Fallback: not sent (e.g. a saved copy, where only the live link can send), so save the picks as a file.
        const a = document.createElement('a')
        a.href = URL.createObjectURL(new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }))
        a.download = 'my-picks.json'
        a.click()
      }
    }
  </script>
</body>
</html>
```

## What you get back

Each reviewer sends one object like this:

```json theme={null}
{
  "reader": "Dana",
  "rows": [
    { "group": "welcome", "best": "B", "why": "Warmer, and the list is useful" },
    { "group": "renewal", "best": "B", "why": "A sounds like a bill" }
  ]
}
```

In the **table**, that's one row per reviewer. Split it on **`rows`** and it becomes one row
per reviewer **per group** (`reader`, `group`, `best`, `why`). Nine reviewers and ten groups
give you 90 rows you can sort, filter, or summarize: the summary then shows how often each
option was picked as `best`.

<Tip>
  Reviewers can change their minds. Sending again **replaces** their earlier picks, so you
  always see each reviewer's latest answer.
</Tip>

<Note>
  Testing in the dashboard preview? It won't send. The preview shows *"Responses are only
  collected on the live link."* Open the published link to try it for real.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.