Dottiq is a multilingual site available in both Japanese and English. On the top page (https://www.dottiq.com), the site auto-detects the user's language settings (navigator.language
and Accept-Language
) and routes them to either the Japanese version (/) or the English version (/en/).
All English pages — such as blogs and tools — live under the /en/
folder. The site doesn’t switch languages per page, but rather determines the user’s language once at the top level and serves all content accordingly.
This setup is clean and SEO-friendly, but if you’re developing in a Japanese environment, previewing the English version becomes annoyingly inefficient.
😩 Changing Chrome’s language settings every time? No thanks
To preview how a page looks in English, I had to manually go into Chrome’s settings and switch the browser language. It affected the entire browser and broke my local workflow.
I just wanted a way to test the English version of my site — quickly and temporarily. When I couldn’t find the perfect tool for that, I built one.
🚀 What is ENforcer?
ENforcer is a lightweight Chrome extension that simulates an English browser environment on a per-tab basis with just one click. It doesn’t translate. Instead, it makes your browser behave as if it were set to English from the start.
🔠 Behind the name
“ENforcer” is a play on words — combining EN
(for English) and enforce
(to apply force). As the name suggests, it forces English — and only English. No other languages are considered.
🔧 Key Features
- Overrides
navigator.language
with"en-US"
- Modifies
Accept-Language
header to"en-US,en;q=0.9"
- Tab-specific toggling — doesn’t affect other tabs
- Persists across page reloads and navigation
- “EN” badge clearly shows when active
- No tracking, no data collection
🔧 Implementation Details
1. Mocking navigator.language
Because you can’t modify navigator.language
directly via JavaScript, I inject a script tag (inject.js
) into the page from content-script.js
. Inside it, Object.defineProperty()
is used to override the browser’s language values.
Object.defineProperty(navigator, "language", { get: () => "en-US" });Object.defineProperty(navigator, "languages", { get: () => ["en-US", "en"] });
To avoid CSP (Content Security Policy) issues, the script is not inline but loaded from within the extension.
2. Overriding Accept-Language
Since Manifest V3 blocks the use of webRequest
with blocking, I use declarativeNetRequest
to rewrite the HTTP header like so:
{ "header": "accept-language", "operation": "set", "value": "en-US,en;q=0.9"}
3. Tab-specific state + badge display
ENforcer stores the toggle state per tab using chrome.storage.local
. When active, it shows an “EN” badge on the icon, so you always know when a tab is in English mode.
😁 Challenges & Considerations
- Some special pages (like
chrome://
or PDF viewers) block script injection, so I had to handle those withtry/catch
. - To avoid store rejection, I clearly explained the need for
<all_urls>
permission in the description and privacy policy. - I made sure settings persist across reloads and navigation using local storage.
🔐 Privacy Friendly
ENforcer collects zero data — no tracking, no storage, no network requests. The full privacy policy is available at https://www.dottiq.com/policies/enforcer.php.
🛒 Get it on the Chrome Web Store
Now available for free: 👉 https://chromewebstore.google.com/detail/enforcer/gokmeebphmjdlgknompgaghdlemiohll
✍️ I built it because I needed it
While working on Dottiq, I had to check the English version of the site over and over. Going into Chrome settings just to flip the language back and forth was tedious and error-prone.
ENforcer was born out of that frustration. If you’ve ever needed to preview your site as an English-speaking user — even briefly — this tool can make your workflow faster and simpler.