How Offline French Autocorrect Handles Accents, Apostrophes, and Typing Errors
Typing French on a standard unaccented QWERTY layout presents continuous friction. Writers must either memorize awkward Alt key codes, toggle operating system input methods, or produce unaccented text missing accents and elision apostrophes.
For bilingual professionals, students, technical writers, and translators, switching keyboard layouts disrupts muscle memory and introduces punctuation mismatches. An alternative approach is offline client-side autocorrection: an in-browser linguistic pipeline that detects unaccented French words, inserts required diacritics, resolves contracted elisions, and rectifies keyboard mis-strikes as you type, using local dictionary indexes and client-side processing.
This guide explains the underlying engineering behind offline French text correction. We examine the differences between general-purpose spellcheckers and diacritic-aware systems, inspect SymSpell-style deletion indexes stored in typed arrays, review Unicode decomposition, and outline how weighted edit distance models distinguish minor accent slips from distinct words.
1. The Challenge of Typing French on QWERTY Keyboards
Standard US and UK QWERTY layouts lack dedicated keys for French accented vowels (é, è, ê, ë, à, â, î, ï, ô, ù, û, ü), the cedilla (ç), and ligatures (œ, æ). To produce these characters without specialized software, users typically rely on one of three options:
- US International layout: Transforms quotes and tildes into dead keys, requiring double presses to type plain apostrophes or quotes.
- Operating system switching: Toggling between QWERTY and AZERTY rearranges key positions (such as A/Q and Z/W), leading to frequent typos.
- Unaccented typing: Typing purely in ASCII letters (e.g., typing
ecoleinstead ofécole) and relying on post-editing or autocorrection.
Unaccented typing is fast, but it leaves words grammatically incorrect. Furthermore, French syntax relies extensively on elision—contracting monosyllabic words like le, la, de, and je before vowels (producing l’, d’, j’). When typing quickly on a QWERTY layout, users frequently omit both the apostrophe and the accent, typing lecole or cest instead of l’école or c’est.
2. Why Standard Unweighted Spellcheck Algorithms Struggle with French QWERTY Inputs
Traditional browser spellcheckers flag unrecognized tokens with red underlines after words are entered. While helpful for post-hoc proofreading, unweighted general-purpose spellchecking algorithms encounter specific structural limitations when applied to real-time French typing on QWERTY keyboards:
-
Uniform edit distance penalties: Under standard unweighted Levenshtein distance, turning
dejaintodéjàrequires two character substitutions (e→éanda→à), costing 2 edit operations. Conversely, turningdejainto an unrelated single-letter typo likedecarequires only one substitution (j→c), costing 1 operation. Because an unweighted algorithm assigns the same unit penalty (1.0) to accent additions as to arbitrary letter swaps, it ranks the incorrect worddecaas mathematically closer todejathan the intended worddéjà. -
Elision tokenization boundaries: Standard word-boundary tokenizers split on spaces and punctuation. When an elided word like
d’accordis typed without an apostrophe asdaccord, or with an unaccented prefix likelecole, a standard dictionary lookup fails because the compound token does not match standard base-form dictionary entries. - Synchronous keystroke overhead: Full morphological affix analyzers or deep rule graphs designed for desktop word processors can be resource-intensive when executed synchronously on every typing delimiter. In browser extensions, keeping computation lightweight avoids blocking the main user interface thread.
3. Architecture of an In-Browser Offline Autocorrect Pipeline
To correct text smoothly in a browser while keeping processing local, an autocorrection engine must evaluate words efficiently on word boundaries without sending text over a network. The pipeline adopted in client-side extensions like Bilexi organizes text processing into clear, sequential stages:
- Keystroke & Word Boundary Detection: Monitors text input and triggers analysis when a delimiter (space, period, comma, or enter) is typed.
- Token Normalization & Elision Splitting: Canonicalizes character encoding and isolates elision prefixes.
- Bloom Filter Membership Gating: Performs a fast bitwise test to verify whether the token is already a known, valid dictionary entry.
- SymSpell Candidate Generation: Generates candidate matches from a precomputed binary index using symmetric deletion.
- Weighted Damerau–Levenshtein Scoring: Evaluates candidates with asymmetric costs for accents, keyboard adjacency, and transpositions.
- Decision & Dispatch: Applies high-confidence replacements directly to the DOM or displays alternative suggestions in an accessible interface.
Rather than relying on runtime WebAssembly or repetitive string parsing, Bilexi structures its reference vocabulary in a binary format. When the extension initializes, it maps typed array views (Uint8Array, Uint32Array) directly over an ArrayBuffer, enabling binary search across pre-sorted hash tables without creating intermediate JavaScript objects on every lookup.
4. Restoring Accents and Handling Unicode Normalization
Accurate diacritic restoration requires careful handling of character representations. In Unicode, accented characters can be represented in multiple forms:
-
Canonical Decomposition (NFD): Represents characters as a base glyph followed by separate combining diacritical marks (e.g.,
e+\u0301foré). -
Canonical Composition (NFC): Combines the base character and diacritic into a single precomposed code point (e.g.,
\u00E9foré).
Unicode normalization forms ensure that text generated across different operating systems compares consistently. However, standard normalization does not fold accents into ASCII letters. To match unaccented typing against an accented vocabulary, the engine applies a custom folding step:
// Canonicalize to NFC for internal comparisons
export function normalize(text: string): string {
return text.normalize('NFC');
}
// Custom diacritic and ligature folding for lookup keys
export function fold(text: string): string {
return text
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '') // Strip combining accent marks
.replace(/œ/g, 'oe') // Expand French ligatures
.replace(/Œ/g, 'Oe')
.replace(/æ/g, 'ae')
.replace(/Æ/g, 'Ae')
.replace(/’/g, "'"); // Unify typographic apostrophes
}
By folding both the reference vocabulary and the incoming unaccented user input to common ASCII keys, words like ecole and école share an identical lookup stem. The original accented forms are preserved in the dictionary data so the engine can reconstruct the proper spelling upon replacement.
5. Resolving French Apostrophes, Elisions, and Name Safeguards
French elision is syntactically mandatory before words beginning with a vowel or a mute h. In natural typing, users omit apostrophes or enter unseparated compounds. The engine handles these through two cooperative mechanisms:
Deterministic High-Frequency Rules
Common uncontracted compounds are mapped directly using curated replacement rules. In Bilexi's implementation, these deterministic rules bypass fuzzy search and apply immediately upon boundary detection:
jai→j’ai(deterministic rule)cest→c’est(deterministic rule)daccord→d’accord(deterministic rule)aujourdhui→aujourd’hui(deterministic rule)lecole→l’école(deterministic rule)
Dynamic Prefix Splitting and Capitalization Safeguards
Beyond curated rules, the engine dynamically evaluates uncontracted elision prefixes (such as l, d, j, qu, m, t, s, n) when followed by a vowel or mute h. In this flow, the tokenizer isolates the candidate prefix and evaluates whether the remaining stem forms a valid French vocabulary entry. For example, jespere is dynamically split into the prefix j and the unaccented stem espere; the stem then matches espère through accent restoration (cost 0.20), successfully producing j’espère as an automatic replacement.
Crucially, the tokenizer incorporates capitalization guards. Single consonants like m, t, s, or n are not treated as elision prefixes when the word begins with an uppercase letter. This safeguard prevents proper names such as Martin or Thomas from being mistakenly split into M’artin or T’homas.
6. Keyboard-Aware Scoring: Physical Layouts and Asymmetric Weights
When an input contains typographical errors beyond omitted accents, candidate ranking relies on a modified Damerau–Levenshtein metric. Rather than assigning an arbitrary unit cost to all operations, the engine assigns asymmetric weights:
Assigning accent restoration a low base cost of 0.20 allows unaccented words to match target dictionary entries ahead of phonetic or typographical alternatives. However, physical proximity or low edit distance alone does not equate to an automatic replacement. The engine's decision logic evaluates candidate ranking against multiple criteria: the candidate must exist in the reference vocabulary, achieve high calibrated confidence, and maintain a decisive score margin over any runner-up candidate. If competing candidates are close in score or confidence falls below threshold, the engine withholds automatic replacement and routes alternatives to the suggestion strip.
7. Safety Limits: When Autocorrection Should Avoid Auto-Replacement
Unchecked autocorrection can be more frustrating than typing mistakes if it replaces intended words with incorrect alternatives. To maintain precision, practical engines enforce strict safety boundaries:
The Short-Word Exclusion Principle
Tokens under three characters (e.g., a vs. à, ou vs. où, du vs. dû, la vs. là) represent distinct, valid French words. Without deep syntactic parsing, replacing a with à on a single-token basis has a high probability of error. The engine explicitly treats tokens with fewer than three letters as no-op candidates for silent automatic replacement.
Morphological Suffix Homophones
In French grammar, verbal endings such as -é (past participle), -er (infinitive), -ez (second-person plural), and -ait / -ais (imperfect) share identical pronunciations and unaccented stems. While client-side engines can use immediate context tokens to evaluate bigram probabilities, fully resolving ambiguous verbal inflections without broader sentence-level syntactic parsing remains difficult. When competing valid forms share close scoring values, the engine avoids guessing with an automatic replacement, routing alternative candidates to the suggestion strip instead.
8. DOM Replacement, Browser Undo Stacks, and Editor Boundaries
Applying a corrected string back into a web page requires interacting with browser text fields. Web applications utilize two primary editing surfaces: standard form controls (<input> and <textarea>) and rich-text containers (contenteditable elements).
Preserving the Native Undo Stack
A common pitfall in browser extensions is updating an element’s value property directly. Mutating input.value bypasses the browser’s native undo buffer (Ctrl+Z / Cmd+Z) and can desynchronize internal state in web frameworks.
To preserve undo history and trigger framework change listeners on standard form inputs and standard contenteditable elements, Bilexi dispatches document.execCommand('insertText') targeted at the active text selection. If an application overrides or blocks execCommand, the extension falls back to setRangeText and dispatches a synthetic InputEvent with inputType: 'insertReplacementText', conforming to the W3C Input Events specification. However, non-standard text surfaces—such as Google Docs canvas mode or custom shadow-root web components that do not expose standard DOM selections—do not support standard insertion commands and cannot be modified by standard content scripts.
The Two-Tier Interaction Model
Not every correction should happen automatically. Bilexi operates across two interaction tiers:
-
Tier 1 (Silent Auto-Replace): Triggered on word boundary keystrokes (space, punctuation, or enter) exclusively for high-confidence matches with a clear margin over any runner-up candidate (e.g.,
ecole→école,cest→c’est). - Tier 2 (Interactive Suggestion Strip): When candidate confidence is moderate or competing dictionary entries are close, a non-intrusive floating chip appears above the caret. Users can accept candidates via keyboard shortcuts (Alt+1, Alt+2, Alt+3) or mouse click.
9. Privacy and Local Architecture Verification
Keystroke processing demands stringent privacy protections. When evaluating any browser tool that monitors text input, it is vital to distinguish claimed privacy policies from verifiable architectural safeguards.
In the reviewed Bilexi production source:
-
Permissions and Site Access: The extension requests only two API permissions:
storage(for settings, custom vocabularies, and user metrics) andactiveTab(invoked when opening the toolbar popup to identify the active domain for per-site toggling). The manifest declares no top-levelhost_permissionsentry. To enable automatic correction as users browse, the manifest separately registers content scripts matchinghttp://*/*andhttps://*/*(withall_frames: true). Content scripts are therefore injected automatically across matching pages at document idle, rather than throughactiveTabinvocations. -
Eligibility and Field Boundaries: Although content scripts inject widely across matching websites, the script executes safety filters before evaluating text. It ignores password inputs, payment and address fields, code editors, search boxes, Google Docs canvas areas, and elements marked with
spellcheck="false"orautocorrect="off". -
Local Packaged Assets: Reference dictionaries (
dict/en.bin,dict/fr.bin) are packaged directly within the extension distribution and loaded into memory viachrome.runtime.getURL(). -
Static Source Inspection: In the reviewed production source and runtime entry points, no explicit user-text upload or telemetry request was identified; networking APIs (
fetch,XMLHttpRequest,WebSocket,EventSource, andsendBeacon) are not invoked for user text.
Note on Verification: This analysis reflects a static source review of the extension package and build entry points, not a continuous live traffic audit in a packet-capture sandbox. While the omission of host permissions restricts standard cross-origin network operations, distinguishing code-level architecture from runtime empirical verification remains essential.
10. Practical Takeaways and Summary
Typing accented French on a standard unaccented QWERTY keyboard does not require disruptive layout switching or memorized character codes. By implementing a client-side linguistic pipeline that combines:
- Precomputed symmetric deletion indexes loaded directly into typed arrays,
- Asymmetric Damerau–Levenshtein weights favoring diacritic restoration,
- French-specific elision splitting with proper name capitalization guards, and
- A two-tier interaction model that reserves silent replacements for unambiguous matches,
writers can produce clean, accented French text naturally, while retaining native browser undo behavior on standard editable fields and keeping text processing on their local device.
Authoritative Specifications and References
The linguistic and architectural concepts discussed in this guide are grounded in the following specifications and research:
- Unicode Standard Annex #15 (Unicode Normalization Forms): Details canonical decomposition (NFD) and composition (NFC) standards. Available at unicode.org/reports/tr15/.
- SymSpell Reference Implementation: Details the Symmetric Delete spelling correction algorithm created by Wolf Garbe. Reference repository available at github.com/wolfgarbe/SymSpell.
- Chrome Extensions Permissions Guide: Official documentation on declaring permissions and host access boundaries. Available at developer.chrome.com/docs/extensions/develop/concepts/declare-permissions.
-
W3C Input Events Level 2 Specification: Defines input event types, including
insertReplacementTextand caret target ranges. Available at w3.org/TR/input-events-2/.
Explore Bilingual Autocorrect with Bilexi
Bilexi executes locally in your browser to restore French accents, resolve elisions, and correct typing slips across web forms using packaged local dictionary assets.