Skip to content

Repository files navigation

Local LLM Translator

A privacy-focused browser extension that translates web pages using local LLMs (Ollama or LMStudio). Your data never leaves your machine.

Get the Add-on

Features

  • 🔒 100% Private - All translations happen on your local machine via Ollama or LMStudio
  • 🎯 Smart Prioritization - Visible content and headings are translated first
  • 🌍 Many Languages - Supports many many languages :3
  • Translation Cache - Optional: translate identical text once and reuse it (great for forums). Off by default; stored locally with a session-only or persistent mode
  • 📖 Glossary - Force consistent translations for proper nouns and UI labels via a user-supplied dictionary
  • 🚀 Auto-Translate - Optional: translate foreign-language pages the moment they load, with per-language and per-site exclusions

Requirements

You need one of these running locally:

  • Ollama (default: http://localhost:11434)
  • LMStudio (default: http://localhost:1234)
  • Any OpenAI-compatible serverllama.cpp's llama-server, vLLM, etc. Put the server's base URL (e.g. http://localhost:8080) in the LMStudio / OpenAI-compatible URL field; a trailing /v1 is tolerated and stripped automatically

With a translation-capable model loaded (e.g. TranslateGemma, tencent.hunyuan-mt, qwen3, etc.)

Installation

Firefox / Mullvad Browser

  1. Go to about:debugging#/runtime/this-firefox
  2. Click Load Temporary Add-on
  3. Select the manifest.json file

Chrome / Chromium

  1. Go to chrome://extensions
  2. Enable Developer mode
  3. Click Load unpacked
  4. Select the extension folder

Coming Soon: Extension in Chrome Web Store

Preview

Extension Screenshot

Usage

  1. Click the extension icon
  2. Select a model from the dropdown
  3. Choose your target language
  4. Click Translate Page

The extension will:

  • Extract all visible text from the page
  • Prioritize headings and visible content
  • Translate in batches with progress percentage
  • Auto-translate new content (infinite scroll)

Privacy

This extension is designed to be privacy-focused:

  • ✅ Only connects to localhost - no external network requests
  • ✅ No analytics or tracking
  • ✅ No data collection
  • ✅ Minimal permissions (only localhost host permissions)
  • ✅ The translation cache is off by default. When enabled it is stored locally (in memory, or IndexedDB for the persistent mode) and never leaves your machine; it can be set to clear on browser close, turned off, or cleared at any time

Settings

Click Advanced Settings to configure:

Setting Description
Provider Auto-detect, Ollama only, or LMStudio only
URLs Custom endpoints for Ollama/LMStudio
Max tokens/items per batch Control batch sizes
Temperature Model creativity (lower = more consistent)
Request Format (work in progress) Default JSON, Hunyuan-MT, Simple, or Custom
Show Glow Toggle visual indicator on translated text
Cache translations Reuse stored translations for identical text — off (default), until browser close, or across sessions; includes a "Clear cache" button
Automatically translate pages Translate foreign-language pages on load, with never-lists for languages and sites — off by default

Auto-Translate

By default nothing is translated until you ask for it. Turn on Options → Auto-Translate → Automatically translate pages and a page is instead translated as soon as it loads, whenever it declares a language other than your target language.

  • Undeclared pages are left alone. The language is read from the page's lang attribute (or a content-language meta tag). Pages that declare nothing are skipped rather than guessed at — a wrong guess would spend real inference time making a page you can already read worse.
  • Only top-level pages. Iframes are skipped, so ads and embedded widgets don't multiply the request count.
  • Escape hatches while it runs. A small bar appears in the corner with Stop (halt and put the original text back) and Never on this site (same, plus adds the site to the exclusion list).
  • Exclusions. Keep a list of languages you already read, and a list of sites to leave alone. Site entries cover subdomains, so example.com also excludes news.example.com.

This needs permission to run on all websites, since the extension has to be present on a page before you have asked for anything. Bear in mind that every page you open now costs a full translation run on your own hardware.

Translation Cache

To avoid re-translating the same text over and over (forum boilerplate, menus, usernames, repeated phrases), translations can be cached locally and reused — both later on the same page and across other pages. It is off by default; enable it in Options or the popup's Advanced Settings.

  • Modes (Options → Translation Cache):
    • Don't cache (default) — every segment is translated fresh.
    • Until I close the browser — cache speeds things up while you browse, then is wiped on the next browser start. Kept in memory, so nothing translation-related lingers on disk between sessions. Works in every browser.
    • Keep across sessions — cache persists on disk (IndexedDB) until you clear it. Best for repeatedly visiting the same sites. Hardened browsers that block IndexedDB (e.g. Mullvad/Tor-based Firefox) disable this option automatically and fall back to the in-memory session cache.
  • What's cached: the translated output for each source text segment, stored locally (in memory, or IndexedDB for the persistent mode) — nothing is uploaded.
  • How it's keyed: by the source text plus everything that determines the model's output — model, source & target language, request format, prompt template, structured-output mode, and temperature. Changing any of these yields fresh translations instead of stale cached ones, so the cache never serves output that wouldn't match your current settings.
  • De-duplication: within a single page, identical strings are translated only once and the result is reused for every occurrence (this happens regardless of cache mode).
  • Clearing: use Clear cache to wipe it at any time (the button shows the current entry count). The cache is capped (oldest entries are evicted first).

Glossary

Load a TSV dictionary (Options → Glossary) to pin translations for specific terms. Each line is source<TAB>translation; leave the second column empty to keep the term untranslated. Matching is case-sensitive. A #target: ja line declares the language the glossary translates into — the glossary is then only applied when that target language is selected (recommended, since a glossary maps terms into one specific language).

It works at two levels:

  • Inside sentences — glossary terms found in the text being translated are injected into the prompt as hard hints, so the model keeps proper nouns consistent (e.g. The Companions同胞団 everywhere). Only matching terms are sent, so a large dictionary is fine.
  • Whole segments — when a segment consists entirely of a glossary term, the mapping is applied directly and the model is skipped. This is the reliable way to fix short context-free labels that small models mangle — e.g. add About<TAB>概要 and the nav heading "About" always becomes "概要" instead of the broken "について".

Whole-segment matches take priority over the translation cache, and loading or clearing a glossary wipes the cache (the same source text now translates differently). Note: models with a fixed prompt format (TranslateGemma, Hunyuan-MT) only get the whole-segment treatment — injecting instruction blocks into their prompts corrupts their output. See examples/ for a sample dictionary.

File Structure

├── manifest.json      # Extension manifest (MV3)
├── background.js      # Background script (LLM API, settings)
├── content.js         # Content script (DOM manipulation)
├── popup/
│   ├── popup.html     # Popup UI
│   ├── popup.css      # Styles (Everforest Dark theme)
│   └── popup.js       # Popup logic
└── icons/             # Extension icons

Development

The codebase is intentionally simple with no build step or dependencies:

  • Pure vanilla JavaScript
  • No external libraries
  • No bundler required
  • Works directly in the browser

Debug Logging

Enable "Enable debug logging" in Options → Output Settings, then Save.

To view logs, go to about:debugging#/runtime/this-firefox, find Local LLM Translator, and click Inspect — messages with [Background] prefix appear in the Console tab.

License

MIT

About

Privacy-focused translation using local LLMs (Ollama, LMStudio).

Topics

Resources

Stars

29 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages