Browser permissions, explained

Every permission Emojery asks for, what the browser's wording actually means, and what the extension can never see.

The 6 permissions

Permission What it grants, in browser terms What Emojery uses it for
storage Store data in your browser's extension storage Your settings and per-site preferences, the signed-in session, a random installation identifier, your recently used emoji, local reaction state and a cache of counts about a minute old. Only the settings travel, through your browser's own sync; the rest stays on the device.
unlimitedStorage Lift the browser's default size cap on that extension storage Keeping your reaction history on your device without the browser evicting it. Browsers show no extra warning for it, because it grants no new access.
alarms Wake the extension's background worker on a schedule Two short wake-ups: retrying reactions queued while you were offline, and refreshing the list of most-used emoji at the top of the picker.
activeTab See the tab you are on, only when you open the extension The popup reads the address of the tab you opened it on, so it can say whether the site is supported, offer that site's own toggle, and fill in the page a bug report is about. It is your click that grants it, and it reaches no other tab.
scripting Run the extension's own scripts, on the sites it already has access to Only one job: the moment you install it, the supported pages you already had open get the reaction button without a reload. It reaches nowhere the host list below does not already cover, so browsers show no extra warning for it.
identity Open a sign-in window to a site the extension names, and read the address that window returns to The Continue with Google, Apple, Microsoft or Twitch button. The window is the provider's own page; the extension sees only the short-lived code the provider hands back at the end, never your password there.

What Firefox shows on the install page

Mozilla requires every extension to declare, in a fixed taxonomy, what data it may handle. Those labels appear on the add-on's install page and can sound broader than what actually happens:

We would rather explain the scary-sounding labels than pretend the extension collects nothing.

What the Chrome Web Store card shows

Google asks every developer to tick, from a fixed list of 9 data categories, the ones the extension "handles", and handling includes data that is only transmitted or only processed on your device. Emojery's card ticks 4. Each one, and what it stands for here:

The 2 we do not tick: Personally identifiable information, and User activity. The first because the sign-in never requests a name, an email or a picture, and the popup labels the account by its provider alone. The second because Google defines it as network monitoring, clicks, mouse position, scrolling or keystroke logging. Emojery records none of those: there is no analytics library, no click or scroll telemetry, and the only keyboard handling is the picker's own search box and focus trap. A reaction you submit is what you said, not a log of what you did, and the timestamps and change count on a reaction row exist so you can change or remove it. If Google's reading of the category ever differs from ours, the card changes, and this page changes with it.

The card also carries 3 certifications: that data is not sold to third parties outside Google's approved use cases, not used or transferred for purposes unrelated to the extension's core functionality, and not used to determine creditworthiness or for lending. The planned API is designed to keep all 3 true: it will serve the aggregate counts the public log already publishes and, at most, a per-country map of reactions with a minimum-count threshold, never anything tied to an account and never the city, language, browser or OS attached to a reaction.

Why it asks for access to specific sites

An extension that draws buttons inside a page needs a content script, and a content script needs host access to the pages it runs on. Emojery requests one https://<host>/* entry per supported host, plus https://api.emojery.app/* so it can talk to its own API and https://emojery.app/* for our own site (what it does there).

Chrome, Edge, and Firefox all phrase host access as the ability to “read and change your data” on the listed sites. The wording is the browser's own, never ours, and it appears for every extension that has a content script. What the script actually does on those sites: it finds the action row of a public post, mounts the reaction button next to it, and derives the public identifier the reaction will attach to.

Each site's content script is also declared statically for that site's hosts only. The Reddit script cannot run on GitHub, and none of them can run on a site that is not in the list below.

Two settings you can turn on use that same access to touch the site's own controls, on the page you are looking at and under your own account: Hide original buttons takes the native control out of view, and Auto-press original buttons links the emoji you pick to the site's own reaction or vote. Auto-press is off until you turn it on, one pick presses at most one control, and removing your reaction releases only what the extension pressed. How auto-press works.

Which sites it can run on

Every host the reaction pipeline runs on, exactly as the manifest lists it. 2 non-platform entries sit alongside them: our API, and our own site (both below). Every platform name links to a page showing what the extension does there.

Platform Manifest hosts
Facebook www.facebook.comm.facebook.com
Instagram www.instagram.cominstagram.com
Reddit www.reddit.comreddit.com
GitHub github.com
GitLab gitlab.com
YouTube www.youtube.comyoutube.com
X x.comwww.x.com
Threads threads.comwww.threads.com
Amazon www.amazon.comwww.amazon.co.ukwww.amazon.dewww.amazon.frwww.amazon.itwww.amazon.eswww.amazon.cawww.amazon.com.auwww.amazon.co.jpwww.amazon.inwww.amazon.com.brwww.amazon.com.mx

Apart from the 2 entries below, it runs nowhere else. A host that is not in the manifest is a host the browser will never inject the extension into.

The 2 entries that are not a platform

What it does not read

When a URL leaves your browser

Sometimes. Here is exactly when.

  1. Showing counts. As supported items scroll into view, the extension asks the API for each one's reaction count, whether or not you react to it. The request contains only a canonical target key, such as youtube/<video-id>, and needs no account; the server answers it without storing or logging the key. While you are signed in, a second request asks which of those items you already reacted to, carrying your session token and up to 50 keys at a time, and is likewise not stored.
  2. Reacting. When you pick an emoji, the request carries a canonical URL that the extension reconstructs from the identifier, with query strings and tracking parameters dropped. It sends https://www.youtube.com/watch?v=<id>, never the raw address from your address bar, along with the emoji, a timestamp, your session token, and the random installation identifier described in the privacy policy. On X and Threads the canonical URL includes the author's handle, because every permalink there does; the server keeps the derived key, not the URL.
  3. Signing in. The extension opens your provider's own sign-in page in a window and, when the provider hands back a short-lived code, sends that code to 1 endpoint in exchange for a session token. Your provider password never reaches the extension. What the server keeps afterwards is covered in the privacy policy.
  4. Reaction context. If the “Community insights” setting is on, which it is unless you turned it off, a reaction also carries your language, and the server attaches the country and city of your connection, your browser family and your operating system. Turn the setting off and those fields stay empty.
  5. Bug reports. The Report tab sends the page address, its host, the site it belongs to, how many targets were found on it, and your note, only when you press submit. With “Community insights” on it also attaches the extension version and your browser's raw user-agent string, so a layout bug can be reproduced on the same build; see what we collect.

Nothing above happens on unsupported sites, because the extension is not there.

What stays on your device

Settings (the master switch, per-site toggles, animation and analytics preferences) sync through your browser's own extension-settings sync and never through our servers.

Turn it off on any site

Click the toolbar icon and open the Settings tab. Turning on Only selected sites gives every supported site its own toggle, and the master Enabled switch turns the extension off everywhere at once. All sites are on by default.

Your browser adds a layer of its own: Chrome and Edge let you restrict any extension's site access from the extensions menu, and Firefox does the same from the add-on's settings.

Delete your account any time

Open the popup's Account tab and choose Delete account. The extension shows a warning and asks you to slide to confirm, so a stray click cannot wipe anything. Deletion erases your account record, reverses every counter you previously contributed to, and clears the local history and session. Your entries in the public log stay, pseudonymous as they always were, each with a public revocation appended after it. It is immediate and irreversible; the details are in the privacy policy. Removing the extension is a separate step, and it leaves the account alone.

What the install prompt asks for

Browsers generate the install dialog themselves from the manifest, so every extension with a content script produces a similar warning. For Emojery the dialog lists exactly the domains from the table above plus our API and our own site, and nothing else.

There is no screenshot here yet, and it cannot be faked: that dialog is native browser UI, and a browser only draws it for an extension installed from a store. So here is the same content read straight off the manifest instead — the 28 domains a browser will name, in the order it receives them.

Firefox prints Mozilla's data-collection notice above that list, using the labels explained further up. The 6 permissions in the first table add no line of their own, which is why the real dialog is shorter than this page.

Common questions

Does Emojery read all my browsing?

No. The extension can only run on the hosts listed in its manifest — the 14 supported sites, plus emojery.app, where a tiny script only stamps the installed version so our own site can tell you already have it. On those sites it asks the server for the counts of the items on screen and stores nothing about the ones you did not react on, and there is no all-sites permission to grant.

Why does the install prompt say it can "read and change" my data on these sites?

That is the browser's standard wording for any extension with a content script; it is not specific to Emojery. On those sites the script mounts the reaction button and derives the public identifier of the item you react to, nothing more.

Does it see private repos or private messages?

On GitHub and GitLab the picker does not show and does not react on private or internal repositories and projects. Direct messages are not a supported surface on any site, so no picker ever mounts there.

Is my browsing history uploaded?

No. The history list in the popup is stored only on your device and never uploaded. What the server does see is a count lookup for each supported item that scrolls into view, sent as a canonical target key rather than your page URL, with no account attached; it answers the lookup without storing or logging the key. The privacy policy describes both requests and what stays behind, which is nothing.

Can I limit it to just one or two sites?

Yes. In the popup's Settings tab, turn on Only selected sites and every supported site gets its own toggle; the Enabled switch above them turns the extension off everywhere at once. Your browser can additionally restrict the extension's site access on its own.

What do the Firefox data-collection labels mean?

They come from Mozilla's fixed taxonomy: authenticationInfo is your session token, websiteContent is the public identifier of what you react to, and there is no personallyIdentifyingInfo label because the sign-in never asks your provider for a name or an email. The optional technicalAndInteraction label covers the "Community insights" toggle, which Firefox asks about separately.

Why does the Chrome Web Store card list location and web history?

Because Google's taxonomy is broad and we fill it in literally. Location covers the country and city derived from your connection when you submit a reaction with "Community insights" on. Web history covers the public identifiers of items the extension asks counts for, and the pages you react on, which are stored with your reaction. Each category is explained below, including the one we do not tick.

Check it for yourself

The manifest is not a promise, it is a public file. Emojery is open source under GPL-3.0, and you can read the permission list, or build the extension from source, in the repository. Anything left over is answered in the FAQ.

The jargon-free overview puts each of these permissions back next to the feature it pays for.