Appearance
How to track uninstalls of a browser extension
Installs are easy to count: the store shows them, and your extension can report its first run. Uninstalls are harder. Once an extension is removed none of its code runs, so it cannot report its own removal. Yet uninstalls are the number that tells you whether people keep what they install. This article covers the one mechanism browsers give you, how it differs between Chrome and Firefox, and how to use it without collecting anything you should not.
The only mechanism: an uninstall URL
Both Chrome and Firefox let an extension name a web address that the browser opens when the extension is removed. Chrome's documentation says runtime.setUninstallURL "sets the URL to be visited upon uninstallation. This may be used to clean up server-side data, do analytics, and implement surveys" (Chrome: runtime API). Firefox implements the same function (MDN: runtime.setUninstallURL).
The rules are the same in both:
- The address must use
http:orhttps:. - It may be at most 1023 characters. Older Firefox versions allowed only 255, so keep it short if you support them.
- Setting it to an empty string stops a tab opening on removal.
When the extension is removed, the browser opens that address in an ordinary tab. Your server receives a normal page request, records it, and answers with a page the person sees.
What an uninstall can tell you
Because the browser makes an ordinary request, your server learns only what you put in the address, plus what any page request carries. Used carefully, that is enough for the questions that matter:
- How many installs are removed, and how that changes from one version to the next.
- How long people kept it, if the address carries the version, or you can match it to an install you counted earlier through a random identifier.
- Which version was removed, which is the quickest way to spot a release that drove people away.
What it cannot tell you is why. For that, the page you open can ask, with a short optional survey. Keep the survey on the page, under the person's control; nothing about it should be filled in from the address.
What it cannot do
- It cannot run your code. The extension is already gone; the page is a website like any other.
- It is not guaranteed. The person can close the tab at once, the browser may be offline, and an extension removed while the browser is closed may not open anything. Treat the count as a lower bound.
- It does not see an extension being disabled. Disabling does not open the address; only removal does, so people who switch it off without removing it are not counted.
Chrome and Firefox behave differently
The functions are the same; the lifetimes are not.
- Chrome remembers the address you set, across service worker restarts. Setting it once, when the extension is installed, is enough.
- Firefox does not keep it for an event page that unloads. If you set it only in the
onInstalledhandler, Firefox forgets it once the background page unloads, and removals stop being recorded with no error anywhere. Set it every time your background script runs, at the top level, not insideonInstalled.
The second difference is the one that silently breaks dashboards: everything looks normal, and uninstalls from Firefox simply never arrive. Test removal on both browsers before you trust the numbers.
Keep the address free of personal data
The address is opened in a normal tab, so it ends up in the person's browser history, can be seen by anyone looking at their screen, and is sent to your server in plain view of any logs it keeps. Put nothing in it you would not put on a public page.
- Do not include an email address, an account ID from your service, a name, or anything the person typed.
- A random install identifier generated by your extension, a version number and a key that says which product the uninstall belongs to are enough for counting.
- Respect a "no". If the person turned analytics off, clear the address with an empty string, so their removal is not reported either. On Firefox, that includes the case where they declined data collection at install.
Your server should treat the request like any other analytics event: count it, and discard the connecting IP address rather than storing it.
Counting uninstalls well
A raw count of removals is hard to read on its own. Two ratios make it useful:
- Uninstalls against installs over the same period. A rising share of removals after a release is a signal; a constant number in a growing user base is not.
- Time to uninstall. Removals within a day of install usually mean the extension was not what the store listing promised. Removals after months are a different problem.
Do not count the uninstall as activity. Someone leaving is not someone using the extension, and counting the uninstall event as a visit inflates the active-user numbers it should lower.
Common questions
Can I find out why people uninstall?
Only by asking. The page you open can offer a short, optional question: what were you hoping it would do, what got in the way. Keep it to one screen, never required, and do not pre-fill anything from the address. A handful of honest answers a week is worth more than a long form nobody completes.
Will the uninstall page count as a visit in my website analytics?
If that page runs your website's analytics, yes: the browser opens it like any other page. Either leave website analytics off that page, or use a dedicated path you can exclude, so a rise in uninstalls does not look like a rise in traffic.
What should the page say?
Thank the person, offer the optional question, and stop there. Avoid anything that tries to talk them back: they have already decided, and a page that nags is the last impression your product leaves.
How do I test it?
Load the extension unpacked, check the address is set, remove the extension and confirm the request reaches your server. On Firefox, wait a minute after installing before you remove it, so the background page has unloaded at least once. That is the case that breaks when the address is only set in onInstalled.
How AnalyticsTrend does it
AnalyticsTrend's extension SDK sets the uninstall address for you when you pass uninstallTracking: true to initBackground, which runs on every background start, so it works on Firefox as well as Chrome. The address carries a random install identifier, the project's public write key, and a marker when the person declined location, nothing else. It is cleared when the person turns analytics off. The collector records the uninstall without counting it as activity, and reports uninstalls beside installs.
What it collects is listed in What it collects. The Firefox difference is covered in more detail in Install in a Firefox extension, and setup in Install in a Chrome extension. For the wider picture, see How to add analytics to a Manifest V3 extension.
Checked against Chrome's and Mozilla's documentation on 7 October 2026.