Keep the internet in your language.
Movar is a cross-browser extension that enforces your language preferences. It prioritizes Ukrainian (with English as a fallback) and automatically steers search engines and multilingual sites away from Russian. Optionally, it can also filter unwanted languages out of on-site language pickers and on-page content, blurring or hiding blocked content cards (Beta, off by default).
Many Ukrainian sites ship UA and RU versions but ignore your stated preference and default to Russian. Search engines surface Russian results even with a Ukrainian locale. Movar fixes that automatically, so you never have to choose.
- Automatic language switching driven by a priority list (default: UA → EN → browser)
- Extension settings override browser language settings
- On-page content filtering — strips unwanted-language picker options and blurs or hides content cards (Beta, off by default)
- Temporary pause (1h / until resumed)
WXT · React · TypeScript · Tailwind CSS · Vitest · Playwright. Targets: Chrome, Firefox, Edge, Opera, Brave, Safari (incl. iOS).
apps/extension # the WXT extension (the published product)
apps/marketing # the Astro marketing site (movar.fyi)
apps/safari-host-app # the Safari wrapper's React host screen (Detector/Settings/About), bundled CSP-safe for the WKWebView
apps/e2e # Playwright end-to-end suites (offline CI + manual live)
apps/diagnostics # local-only detection diagnostics (dev, never published)
packages/brand # brand & contact constants (support, feedback, source URLs)
packages/events # correction-log types (the local dashboard record)
packages/settings # settings schema, defaults + locked-language invariant
packages/lang-detect # UA-vs-RU language detection + BCP-47 code normalization
packages/lang-pickers # on-site language-picker discovery + model (redirect layer)
packages/page-content # per-site content extractor model (content-filter layer)
packages/page-language # page-language verdict that drives redirect decisions
packages/page-mode # page color-scheme (light/dark) detection
packages/host-match # shared host predicates (isGoogleHost/isYouTubeHost); redirect rules live in apps/extension/src/sites/
packages/app-shell # shared React shell (mountApp + StrictMode + crash ErrorBoundary) every surface mounts inside
packages/i18n # UI string catalogues (en/uk) + the browser-free React I18nProvider
packages/options-ui # shared, storage-agnostic options/popup UI (settings sections + pickers)
packages/theme # design tokens (colors/space/fonts/radii/breakpoints/sizes): typed source -> generated CSS
packages/ui # shared design-system primitives (extension + marketing)
pnpm install
pnpm dev # WXT dev server (Chrome by default)
pnpm build # build all packages/apps
pnpm lint
pnpm typecheck
pnpm testFor fast popup/options iteration without loading the extension into a browser,
the extension ships a static-serve preview that inlines a WebExtension API
shim — see apps/extension/preview/README.md.
For anything that touches real chrome.storage, the background worker, or
content scripts, use pnpm --filter @movar/extension dev:firefox:installed
instead.
New to the codebase? CONTRIBUTING.md is the contributor
entry point (setup, the two-layer mental model, where a site rule lives, the
gate commands), and docs/glossary.md defines the domain
jargon (SERP, curtain, the two layers, the package map) so the rest of the docs
read clearly.
See apps/extension/AGENTS.md for the extension's
architecture overview (entrypoints, the two-layer pipeline, the build). Editing
user-facing strings (popup, options, content curtains, marketing site, store
listings)? See docs/copy.md — voice, lexicon, mechanics,
length-and-register caps.
- Code health
81 (B)— fallow maintainability score, 0-100 with an A-F grade, over complexity, duplication, dead code, and churn; refreshed bypnpm metrics. - Coverage
94% lines · 86% branches— Vitest (v8) line and branch coverage, aggregated across the test-bearing workspace projects weighted by size; snapshotted bypnpm metrics. - Content.js
37 KB (source graph)— source-graph size of the always-on content script (the esbuild import graph of content.ts, measured bycheck:content-bundle; the real emitted artifact is ~40 KB, gated at 48 KB by wxt.config.ts) — franc and the language profiles live in the background worker, not here; snapshotted bypnpm metrics. - License
MIT— SPDX identifier read from the rootLICENSEfile. - Promises
3/3 kept— public claims from movar.fyi (apps/marketing) verified against the code each build —pnpm check:readmefails if any breaks:- ✓ Open source — root LICENSE is MIT, an OSI-approved open-source license (marketing: hero badge + footer)
- ✓ Nothing leaves your browser — manifest declares data collection 'none', no analytics dependency, and no fetch/XHR/WebSocket/sendBeacon in the extension runtime (marketing: hero badge + privacy section + limitations)
- ✓ On-page filtering stays off until you turn it on —
defaultSettings.contentModificationis false in @movar/settings — DOM filtering ships opt-in (marketing: how-it-works step 2 + limitations)
- Permissions
3 requested— browser permissions the extension manifest requests, each scoped to one job:storage— persist your settings, pause state, and the local corrections log (preferences sync; state stays on-device)declarativeNetRequest— rewrite the outgoingAccept-Languagerequest header to your preferred language order via one declarative rule — request and response bodies are never readalarms— auto-resume Movar when a timed (1-hour) pause expires<all_urls>host access — run the language-correction content script on whatever site you allow it — requested at runtime on Chrome/Firefox (a one-click native prompt, see the onboarding page), granted at install on Safari; no page content or browsing history leaves the device
- Lines of code
40.6k— TypeScript underapps/+packages/, tests excluded; snapshotted bypnpm metrics. - Suppressions
42 eslint-disable · 25 fallow-ignore— inline lint / complexity opt-outs across the tree; the fallow-ignore set is budgeted and each is justified at the call site.
Generated by pnpm gen:readme from committed sources; the code-health score and coverage are snapshotted by pnpm metrics.
Next up (v1.3.0): Movar on the iOS & iPadOS App Stores — macOS is live — plus a
card-scoped diagnostics view for maintainers. See docs/ROADMAP.md and the
GitHub milestones.
MIT