Benchmark: language detection on real marketing copy

We tested the offline trigram engine behind Lingua Detective against the hardest corpus we could find: this site's own marketing copy — short strings, brand names, prices and technical terms, in 36 languages. Everything below is reproducible with one script.

80.6%top-1 accuracy, full pages (29/36)
83.3%correct language in top-5 (30/36)
64.3%top-1 on short strings (≥25 letters, 3,701 samples)
0.39 msaverage per detection (3,737 calls, single core)

Methodology

The corpus is the real i18n copy served on this site (36 locale files, every user-facing string). Two trials per language:

Brand tokens, URLs and placeholders are stripped first. Engine: franc 6.2 (offline trigrams; the same model the production /detect endpoint runs). Script and raw output are public: benchmark-detection.mjs · benchmark-detection.json. Raw JSON uses French field names; English aliases are not available. Run date: 2026-09-13.

What the numbers say

Full pages are reliable; short strings are genuinely hard. On page-length text the engine names the right language first in 29 of 36 cases, and puts it in the top 5 in 30. On isolated short strings — a button label, a tagline — top-1 accuracy drops to 64.3%. That gap is exactly why Lingua Detective never judges a page from one fragment: it reads a short sample, then the full text with the repeated template removed, and only then issues a verdict (with AI arbitration on doubtful pages).

Where the raw engine misses (full pages)

LanguageDetected asWhy it happens
Croatian (hr)Serbian (srp)Sister languages share most trigrams — the miss is between mutually intelligible neighbors, not random noise.
Malay (ms)Indonesian (ind)
Irish (ga)Scots (sco)Small training footprint + mixed English loanwords in marketing copy.
Icelandic (is)Swedish (swe)Low-resource languages against marketing vocabulary full of technical English terms.
Luxembourgish (lb)Low German (nds)
Māori (mi)Swahili (swh)
Maltese (mt)Norwegian Nynorsk (nno)

Note: franc distinguishes fine-grained codes from macrolanguages (ekk for Standard Estonian, lvs for Standard Latvian) — we count those as correct.

Why we still run an offline engine

Reproduce it

npm install franc
node benchmark-detection.mjs   # against a local checkout of this site's locale files

The corpus is this site's own public locale files (/i18n/locales/{en,fr,es,…}.json). The script prints the per-language table and writes the raw JSON.