How to collect feedback for a Chrome extension

A Chrome extension cannot load the widget script into its own pages, so it sends feedback with fetch to the Escuta Produto REST API. Use the popup or options page for reports, set the hosted form as the uninstall URL for one short exit question, and add the extension version to every item.

By · Last updated

Why an extension cannot use the widget script

A Chrome extension runs its pages from its own package, and Manifest V3 forbids loading code from a remote server into those pages. The widget is a script tag that loads widget.js from the Escuta Produto domain, so it cannot run in the popup, the options page or the service worker.

The extension can still collect feedback. It sends a request to the REST API from its own pages. The request has the same shape as the one a website makes, and the REST API reference lists every field. Two other tools fit the extension model well: the uninstall URL, which asks one question when someone removes the extension, and the hosted form, which works in any browser tab.

Give the popup a feedback form

Cross-origin requests from extension pages need permission in the manifest. Add the Escuta Produto domain to host_permissions:

{
  "host_permissions": ["https://escutaproduto.com/*"]
}

Next, send the message from the popup with fetch. The function below builds the request, includes the extension version and optionally reads the URL of the tab the user is on:

async function sendFeedback(message, kind = "other") {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  const response = await fetch("https://escutaproduto.com/api/v1/feedback", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      key: "pk_your_product_key",
      kind,
      message,
      pageUrl: tab?.url,
      metadata: { extensionVersion: chrome.runtime.getManifest().version },
    }),
  });
  if (response.status !== 201) {
    throw new Error("Feedback failed with status " + response.status);
  }
  return response.json();
}

The public key is safe in the extension package, because anyone can read the code and the key can only create feedback. The API returns 201 with the new item id when the message is saved.

Reading the tab URL needs the right permissions. If your manifest does not grant access to the active tab, leave pageUrl out. The message is still saved, and you can ask the user for the page in the text when it matters.

Tag every report with the extension version

The extension version is the single most useful piece of metadata. Chrome users update at different speeds, so a bug report can come from three releases at once. chrome.runtime.getManifest().version returns the version from your manifest, and the function above sends it with every report.

If you also support a browser build or a store channel, add it as another key, such as channel: "beta". Keep the metadata to a few short values. It is stored as JSON and must stay under 4 KB.

Version numbers answer the first question a maintainer asks: did this start after the last update? Without them, you spend a day asking the reporter which version they run. With them, a cluster of reports that all name version 3.2.0 points straight at the release that broke something. The inbox does not filter by metadata, so note the version in the first triage pass and record the release in an internal note when you confirm the bug.

Keep the popup form short. Four controls are enough: the four types as buttons, a message box, an optional email field and a line that says the current page address is included. A longer form in a small popup gets closed before anyone finishes it, and that feedback never reaches you.

Use the uninstall URL for one question

Chrome lets an extension open a page when the user uninstalls it. Set that page in the background service worker when the extension installs:

chrome.runtime.setUninstallURL("https://escutaproduto.com/f/your-product-slug?lang=en");

The hosted form is a good fit because it needs no code and no sign-in. Keep the question simple, for example "What made you remove the extension?", and make it clear that the answer is optional. The form does not know who uninstalled, so do not promise personal follow-up unless the person writes an email address in the form.

Use the uninstall page sparingly. Uninstall is a moment of frustration, so a respectful, short message helps more than a long survey. The article on cancellation feedback describes the same tradeoff for paid products.

The options page is where people look for help. Add a plain link to the hosted form, opened in a new tab:

<a href="https://escutaproduto.com/f/your-product-slug?lang=en" target="_blank" rel="noopener">Send feedback</a>

Use the popup for in-context reports, where the page URL is useful, and the options page for general ideas and praise. A bug button in the popup footer works well for "something broke on this page".

Check the allowed origins

Allowed origins protect the widget from being used on sites you do not control. They also apply to browser requests to the API. An extension request sends an Origin header that starts with chrome-extension:// followed by the extension ID.

If you have set allowed origins for the product, the extension's origin must be on that list, or the API returns 403. Check how the settings field expects the value, then send a test message from the popup and confirm that it saves. If you do not use the widget on any website, you can keep the product's origin list empty, but read the REST API reference first to confirm how the check behaves.

Set up Escuta Produto for your extension

Create a product for the extension, copy the public key and add the Escuta Produto domain to host_permissions. Build a small feedback form in the popup with four types: bug, idea, praise and other. Send each item with the extension version in metadata, then open the inbox and check that the version appears on a test report.

Add a webhook so new reports reach your team. The notifications guide explains the setup. Once a fix ships in a new version, reply to the people who reported the problem. The article on collecting feedback before launch covers the same hosted-form approach for early testers, and collecting feedback from release notes shows how to tie a version to the requests it answers.

Frequently asked questions

Can I load the feedback widget script inside a Chrome extension popup?

No. Manifest V3 does not allow remotely hosted code to run in extension pages, so the widget script cannot load there. Send feedback with a fetch call to the REST API from the popup or options page instead.

Can the uninstall page know which user is leaving?

No. The uninstall URL is a plain address that Chrome opens after removal, so it carries no user details. Keep the question short and let people answer it without signing in.

Why might my extension get a 403 response?

If the product has allowed origins set, a browser request must come from one of them. Extension requests carry an extension origin, so add it to the list and test again. Check the origin rules in the REST API reference.