Spell Checker

Maya runs the customer-success tooling team at a mid-sized B2B SaaS company. Last sprint her PM dropped a ticket on her: the CRM's "Account Notes" field needs to behave like a real word processor -- formatting, links, and, most importantly, a red squiggle under typos. Support agents type fast, often in noisy contexts, and a missing spell-checker is making the company look unprofessional in customer-facing exports.

She drops a WinFormHtmlEditor on the notes form, hits F5, and types "Customer reportted the issue at 3pm." A red squiggle appears under reportted before her finger leaves the keyboard. She right-clicks, picks reported, and moves on. The whole investigation took ninety seconds. The US English dictionary is embedded inside the control -- nothing to install, no native DLLs to ship, no dictionary files to bundle.

WinFormHtmlEditor showing a red squiggle under a misspelled word with the right-click suggestion menu open

Two ways to check, and you choose per workflow

Maya's agents want the squiggle-as-you-type behaviour. Her compliance team, who later review and clean up the notes in batch, want the old-school modal dialog that walks one mistake at a time. The control supports both, and the choice is one property:

// Live, as-you-type squiggles for the agents
editor.SpellCheckOptions.FireInlineSpellCheckingOnKeyStroke = true;

The dialog mode is always available regardless of that flag -- it fires when the user clicks the Spell Check button on the toolbar, or when Maya calls the spell-check command from her own menu. The dialog walks the document one mistake at a time with Change, Change All, Ignore, Ignore All, and Add buttons. Compliance is happy; agents are happy.

WinFormHtmlEditor Spell Check dialog showing a misspelled word, ranked suggestions, and Change / Ignore / Add buttons

Two months later: the German rollout

The CRM ships in Germany. The German support team types in German, and US English squiggles every other word. Maya needs the editor to switch dictionaries based on the agent's profile language.

The control ships with embedded dictionaries for fifteen languages. They live behind a single enum, SpellCheckLanguage, on the SpellCheckOptions object. Switching is one assignment:

using SpiceLogic.HtmlEditor.Abstractions.Entities.SpellCheck;

private void ApplyAgentLanguage(string agentLocale)
{
    editor.SpellCheckOptions.SpellCheckLanguage = agentLocale switch
    {
        "de-DE" => SpellCheckLanguage.German,
        "fr-FR" => SpellCheckLanguage.French,
        "es-ES" => SpellCheckLanguage.Spanish,
        "pt-BR" => SpellCheckLanguage.PortugueseBr,
        _       => SpellCheckLanguage.EnglishUs,
    };
}

Embedded languages include English (US and GB), German, French, Spanish, Italian, Dutch, Danish, Polish, Norwegian, Czech, Swedish, and both flavours of Portuguese. The default value, SameAsEditorLanguage, follows whatever the editor's UI language is set to -- useful when the application already localises and Maya does not want a separate switch.

The language that wasn't in the box

Six months in, the company opens a Polish hospitality vertical and the medical-records team in Warsaw needs Polish plus a specialised veterinary terminology dictionary that someone in the lab has curated as a LibreOffice .dic / .aff pair. The control accepts any OpenOffice-format dictionary; Maya points the file paths at the lab's pair:

editor.SpellCheckOptions.DictionaryFile.DictionaryFilePath = @"C:\Dictionaries\vet_pl.dic";
editor.SpellCheckOptions.DictionaryFile.AffixFilePath      = @"C:\Dictionaries\vet_pl.aff";

On-disk paths always win over the embedded enum value, so the lab's file pair takes over the moment those properties are set. Clearing both paths drops the editor back onto whatever SpellCheckLanguage selected.

The "block submit until clean" requirement

Maya's compliance lead has one more ask: agents must not be allowed to submit a note containing flagged typos. She wires up the completion event and gates her save button on the result:

editor.SpellCheckCompleted += (sender, args) =>
{
    saveButton.Enabled  = args.MisspelledWordCount == 0;
    statusLabel.Text    = args.MisspelledWordCount == 0
        ? "Ready to save."
        : $"{args.MisspelledWordCount} word(s) need attention.";
};

SpellCheckCompleted fires at the end of every dialog pass, giving Maya a single hook for statistics, progress UI, or workflow gates.

When a 12,000-line note gets opened

One of Maya's power users pastes a 12,000-line compliance audit into the notes field. The first time inline checking runs across the whole document, she wants to drive the moment herself rather than wait for the user to type. Two methods give her direct control:

  • editor.ForceInlineSpellCheck() -- run the inline pass on demand, typically right after a programmatic content load.
  • editor.CleanUpInlineSpellCheckMarkers() -- strip every red squiggle from the document, useful before generating the PDF export or showing a clean print preview.

The inline engine itself coalesces bursts of keystrokes through a debounce window (300 ms by default), so even on the 12,000-line note Maya's agents never see typing lag while the engine catches up.

What ships

Maya's notes field went from "plain textbox" to "multi-language, compliance-gated, end-user-extensible" in a single sprint, with zero deployment changes -- no extra installer steps, no native runtime, no dictionary bundles. The agents-add-their-own-words story is on the User Dictionary page; the corporate-terminology-server story is on the Using a Custom Spell-Check Engine page.

Last updated on May 12, 2026