Deep dive
How Movar works
Saying "Movar sees that the page is Russian" is easy, but it is the hardest part of the whole job — and the reason shows when the signals disagree. The language switcher shows "UA" as active. The <html lang> attribute says ru. The classifier, reading the text itself, returns a third answer. Who is right? This page walks through how Movar weighs the evidence, the rules it works under, why it refuses to translate, and where its reach ends.
01
A ladder of signals, strongest first
Movar settles the disagreement by weighing evidence rather than taking a vote. The first signal that answers decides.
- First is the active entry in the site's language switcher, and it outranks <html lang> even though intuition says otherwise. The switcher is drawn by the same code that draws the content: they are built together and almost always agree.
- Second is <html lang>. It sits in a template and lives its own life — some sites serve lang="ru" on every locale without exception.
- Then the subdomain ru.example.com, then a path segment matched strictly, so that /ru-return-warranty does not read as ru, and finally self-hreflang, where the page points at itself with a language tag.
- When all five stay silent, the text of the page is what is left. Here Movar tries the browser's built-in language detector — Chrome and Edge ship one: where it is available it is the more accurate option, and where it is not, franc runs against local trigram tables. That is the sixth and last step for a whole-page verdict.
- Where the evidence runs out, the verdict is "unknown" — and Movar touches nothing.
02
Short strings need a different classifier
A verdict for the page is not the end of it. A product card, a menu item, a result heading each have to be classified on their own, and a three-word string is too small for both AI and trigrams.
- The obvious approach is distinctive letters: і, ї, є, ґ against ы, ё. On a paragraph it works beautifully; on a short title with none of them it stays silent, and on a quotation it lies. So letters are not the whole method here — only the first rung of four.
- The rungs in order: distinctive letters, then hand-picked function words with the highest precision, then frequency words generated from a subtitle corpus, and finally franc — a trigram backstop, and only for text of 24 characters or more. The rung whose leader pulls ahead by at least one wins.
- "Distinctive" means not "unique in the world" but "unique among the languages we are telling apart right now". The letter і settles Ukrainian against Russian, because only the first has it — but between Ukrainian and Belarusian it decides nothing, because both do.
- When the card carries a language tag of its own — Google labels its AI answer block with a proprietary attribute — Movar weighs tag and text together: the tag decides while there is little text, but a confident read of the text overrides it. A card labelled Ukrainian that is really Russian doesn't get to hide behind its label.
- The conclusion comes back with its evidence, not just a language code: which rung fired, by what margin, and whether there was anything to choose between at all. And where the votes split, the verdict is "unknown" — which for Movar means "leave it alone".
03
The classifier grew into its own package
This part eventually outgrew Movar: the classifier, the language profiles, and the codes moved into a separate package published on npm.
- langtell answers a different question from franc or cld3. Not "what language is this text" but "what language is this heading, given the page and the headings it arrived with" — and it shows what the conclusion was built from.
- It reads more than the text itself: <html lang>, og:locale, and the Content-Language header all count as evidence, and the verdict comes back with a list of what influenced it, so it is always visible why a string was classified the way it was.
- Its Cyrillic set is wider than Movar needs — Serbian, Macedonian, and Kazakh are in there too — so anyone can take it for their own pair of languages. Zero required dependencies, MIT, and franc plugs in separately and only when needed.
- What stayed in Movar is what is specific to Movar: the fast heuristic for the main path, the engine orchestrator, and BCP-47 normalisation. All of it on the device: no request out, no telemetry. That is a condition, not a side effect.
04
Rules Movar holds itself to
Behind each of these decisions is a rule that stays in force even when breaking it would be convenient.
- Switch first, hide last. Movar is not a blocker: its main job is to find the Ukrainian version that already exists and switch the site to it.
- Shared mechanisms, not a list of sites. The header, hreflang, markup, and language switchers exist everywhere, so the base layer works on a site Movar has never seen. The page models for Google and YouTube are an extension, not the foundation.
- The criterion is language, not content. Movar does not judge texts or attach labels to them.
- Better to miss something Russian than to hide something Ukrainian by mistake. The whole detection mechanism runs on evidence, and "not sure" means "leave it alone".
- An explicit choice by the reader outranks a setting. If you clicked "Russian" on a site yourself, Movar does not throw you back — it stands down on that site for the rest of the session, at most a day. Otherwise the extension would be undoing your own choice.
- No content filtering by default. Hiding content is off until you turn it on in the settings.
- All processing on the device, AI included. Opportunistic, not required: where a built-in detector exists Movar uses it, and where it does not, local algorithms do the work. It never downloads AI models and never demands a newer browser.
- No looking inside media. Movar does not read text inside images, video, or audio. That is a principle and a limitation at once.
- No analytics. No counters, no telemetry, no "anonymous statistics".
- The promises are checked by a program. Each one is verified against the source on every build: "nothing leaves your browser" is a check that scans the sources for network calls and fails the build if it finds one. Not marketing, a test — live results on the Transparency page.
- Never translate. Not ever, not even as an option. The next section is about exactly that.
05
Why Movar never translates
The obvious response to "this text is in the wrong language" is to translate it. Movar refuses on principle, and it is probably the most important decision in the whole product.
- What does it do with the Russian still on the page? Neither translates it nor hides the page wholesale. It removes individual elements, exactly the ones in a blocked language: the "Russian" entry in a language switcher, a Russian result in Google's listing, a video card on YouTube. The rest stays as it is.
- Translation launders the source. Machine Ukrainian reads like the real thing, and you are alone again with exactly the content you fenced yourself off from — now in a language you trust, propaganda included. The signal "this is Russian" is the thing people install Movar for.
- Translation stalls Ukrainian. The Ukrainian-language audience is invisible to the people making content — it dissolves into the Russian-language numbers. The reader is satisfied and the author never learns that their audience would rather read Ukrainian. The demand stays invisible.
- When there is no Ukrainian content, there are exactly two honest options: show it as it is, or hide it. You choose which: filtered content either disappears or stays in place behind a blurred curtain.
- Movar does not sort authors into right and wrong. Propaganda hides behind Ukrainian perfectly well — language alone guarantees nothing about the quality of a text. A pro-Ukrainian author writing in Russian is caught by the filter too, because the criterion here is language, not loyalty. Any other criterion would turn a language tool into something else entirely.
06
What Movar can't do
It would be dishonest to pretend the extension fixes everything.
- Movar fixes what happens in your browser: the request that gets sent, the URL you open, the search parameters, the switcher it already knows for a site. It doesn't edit cached CDN responses, retag misclassified Wikipedia articles, translate text baked into an image, or make an AI answer in Ukrainian.
- The item-by-item filter has a hard edge. To remove a card, Movar has to understand the page structure, and right now it knows Google results and YouTube. On a marketplace it cleans up the switcher and leaves the product cards. Every new structure is its own rule — the honest answer to "what about my site?".
- YouTube has no equivalent of Google's lr — no parameter that genuinely filters out Russian-language video; hl and gl only nudge the interface, the ranking, and the recommendations. The URL guarantees nothing there, and the only thing that removes Russian cards is the same item-by-item filter you switch on by hand.
- When a Ukrainian-only Google filter returns an empty page, Movar re-runs the query once without it. Insisting on the language to the bitter end would mean showing you zero results instead of the ones that do exist.
- But a clean signal is the precondition for everything else. While the systems see a muddy signal, detectors, ranking, and AI answers will keep pointing at the wrong language.
Like the idea? Get involved
Movar is non-commercial: no paid tier, no premium features, no data for sale. There is one goal — more Ukrainian on the internet. Four things help most. An honest review in an extension store: ratings are how stores decide who to show an extension to. Telling people about it — everyone who switches Movar on is one more clean signal in the same statistics that localisation budgets grow from. A bug report about a site where Movar missed, or fired where it shouldn't have: each one becomes a test and stops recurring. And design — icons, illustrations, store-page assets; that is what is in shortest supply.