The short version
- No account, no telemetry, no analytics, no ads. The only server of ours the extension can talk to is the optional TransFlow Cloud relay — it sees the text it is asked to translate and counts a daily quota. It never logs or stores request content: the text is forwarded and discarded. It can be switched off entirely in Settings.
- Text is sent to a translation provider only, and only the provider your settings choose. You can run the extension entirely on your own machine.
- Everything the extension remembers (history, settings, usage counters) stays in your browser's storage.
What leaves your machine, and when
The extension translates through a chain of engines. Which engine runs decides which — if any — network request carries your text:
| Engine | Where text goes | When it runs |
|---|---|---|
| Chrome Built-in AI | Nowhere — runs on-device inside Chrome | Always available; used when the chain reaches it |
| Local Ollama | Nowhere — localhost only | If you installed Ollama and enabled it |
| TransFlow Cloud | api.transflow.dev (project's gateway → LLM upstream) | While enabled in Settings — translation and generative tasks when the chain reaches it. The relay authenticates an anonymous install token, counts daily quota, forwards the text, and discards it — no logging, no storage, data_collection: deny on upstream |
| Cloud Gemini | generativelanguage.googleapis.com (Google) | Only after you enter your own API key; for tone, analysis, rewrite, summarise, and as a fallback |
| Local TTS server | Nowhere — localhost only | If you run server/ and select its voices |
The published extension never calls Google's own web endpoints directly — the managed gateway carries that traffic. The source tree still contains that optional path for platforms that opt in (lib/google-direct.js); on the store build it is switched off.
Specifics worth knowing:
- Selected text is sent for translation when you trigger a translation. The "Private / offline" routing mode tries on-device engines (Ollama, then Chrome's built-in model) first; only when they cannot translate does the text fall back to TransFlow Cloud, and only while it is enabled. Turn off "Use TransFlow Cloud" to guarantee nothing leaves your machine.
- Page context: when Cloud Gemini translates a selection, the surrounding paragraph (max ~1,200 characters), page title and domain are sent with it so the model can resolve ambiguity. Deterministic engines never receive this.
- Page translation sends the text of page paragraphs to the chosen engine chain, batched. Pages on your blocklist are never touched.
- Input translation (triple-space) sends only the text you typed in that field, and only when you trigger it.
- Images: region captures, screenshots and uploaded images are downscaled and cropped locally before being sent to the vision engine you selected (a local Ollama vision model first, then TransFlow Cloud, then Cloud Gemini with your own key). A region capture sends only the area you drew.
- Text-to-speech sends the text being read aloud to the engine you assigned for that language. The default is your operating system's voices, which is fully local.
What stays on your machine
- Settings — stored in
chrome.storage.sync(synced by Chrome under your own Google account, if browser sync is on) orchrome.storage.local. - Gemini API key — stored in
chrome.storage.syncunder your Chrome profile. It is sent only to Google's Gemini API endpoint. It is never sent to, or seen by, the extension developer. - Install token & license key — the gateway mints an anonymous install token (
/v1/install) which is stored locally and sent only toapi.transflow.devto identify quota. An optional Pro license key you enter is likewise sent only to the gateway for verification. - History / phrasebook — your last 50 translations and saved entries are stored locally and are never transmitted. Clearing or exporting them happens entirely on your machine.
- Usage counters — counts of requests and characters, stored locally, never transmitted.
Permissions, in plain terms
| Permission | Why the extension asks for it |
|---|---|
storage | Settings, history, phrasebook, usage counters |
contextMenus | Right-click "Translate / Explain / Translate this page" |
sidePanel | The side panel surface |
offscreen | One document that owns the engines and audio, shared by every surface |
activeTab, scripting | Inject the content script into a tab that was open before install, when you first use it there |
<all_urls> (content script) | Translation must work on any page you browse; the blocklist removes pages you name |
api.transflow.dev host permission | The managed-cloud tier — the only host the project operates |
localhost host permissions | Optional local Ollama and local TTS server — only ever reached on your machine |
Third parties
The extension talks to Google only when you supply your own Gemini API key and your routing reaches that tier. Those requests are governed by Google's own privacy policy. The TransFlow Cloud gateway (client side auditable in lib/gateway.js) relays to LLM upstreams (e.g. OpenRouter) with data-collection denied where the provider supports it; it stores quota counters (token/key hashes, salted hashes of network addresses for per-network limits and abuse bans — never the addresses themselves) and daily per-route counters (calls, errors), never the text itself. Ollama and the bundled local TTS server are software you run yourself; the extension does not send them anything that leaves localhost.
Children's privacy
The extension does not collect personal information from anyone, including children.
Changes
Any change to this policy ships with the extension and is committed to this file in the public repository.
Contact
Questions: [email protected], or open an issue on the GitHub repository.