Skip to Content
FrontendBundlesIconsKeywords & Translations

Keywords & Translations

script/generate-keywords.py actually reads three files, not two:

FileRoleDocumented where
mapping.json (per icon set)Source of which icons exist — the generator loops over its keys (classnames)Adding New Icons — it isn’t specific to search, it’s the same mapping.json used to build the icon library itself
translations-en-fr.jsonSource of French wordsThis page
keyword-overrides.jsonSource of per-icon synonymsThis page

This page covers the two hand-maintained files that exist specifically for search — what each one is for, and how script/generate-keywords.py combines them with mapping.json to produce keywords.json. For how the result is actually consumed in the UI, see Search in IconDropdown.

Two files, two different jobs

Both files live in script/, next to the generator. Neither is imported directly by the app — they only exist to feed the generator, alongside the mapping.json of whichever icon set is being processed (see table above).

FileAnswers the questionKeyed by
translations-en-fr.json”What’s the French word for this English word?“a single English word
keyword-overrides.json”What extra search terms does this exact icon need?“a full icon key

They exist separately because they solve two genuinely different problems — mixing them causes real bugs (see When word-by-word translation isn’t enough below).

translations-en-fr.json — word-by-word dictionary

A flat { "english word": "french word" } map, currently 937 entries. The generator splits an icon’s classname into words and looks each one up here.

{ "bank": "banque", "equals": "égal", "folder": "dossier", "user": "utilisateur" }

Example: glyphicons-v2/halflings bank → the classname is bank → looked up → "banque" becomes a search keyword. Searching “banque” now finds it, in addition to "bank".

A word not in this dictionary is not an error — it’s just left untranslated (the icon still works, it simply isn’t French-searchable for that word). Never assume every icon has a translation; see Adding New Icons for what’s actually required vs. optional.

keyword-overrides.json — per-icon synonyms

A { "full icon key": ["keyword", "keyword", ...] } map, currently 83 entries. Used when a translation isn’t enough — the icon needs a synonym that has no linguistic relationship to its own name.

{ "social social-pocket": ["pocket", "lire plus tard", "read later"], "social social-google-drive": ["google drive", "drive", "stockage", "cloud"] }

When word-by-word translation isn’t enough

Take the “Pocket” app icon (social-pocket). Its whole name is one word: pocket. There is no English-to-French translation that turns “pocket” into “lire plus tard” (“read later”) — that’s not a translation, it’s knowledge about what the product does.

Don’t be tempted to “fix” this by adding "pocket": "lire plus tard" directly to translations-en-fr.json. It technically works for that one icon, but TRANSLATIONS is global — if “pocket” (or any word) ever appears in a different icon with a different meaning, that icon silently gets the wrong translation too. Keeping synonyms in keyword-overrides.json, keyed per-icon, makes that impossible: an override can never leak into an unrelated icon.

Exceptions: when a word means something different depending on where it is

Some words genuinely need two different translations depending on which icon set they’re in. The generator handles this with PER_SET_OVERRIDES, a table of per-file exceptions that override translations-en-fr.json only for that one file.

WordGlobal meaningReal meaning in…File
bintrash (poubelle)a .bin binary fileglyphicons-v1/filetypes/mapping.json
loglogin (connexion)a .log fileglyphicons-v1/filetypes/mapping.json
ticketan event/parking ticket (billet)a support ticketphpc/frontend-favicons/ticket/mapping.json
applethe fruit/brand (pomme)fixed web standard term (apple-touch-icon)all 10 phpc/p-icon/*/mapping.json

If you ever see an icon with a nonsensical French keyword (e.g. a support ticket icon getting “billet”), this is almost certainly the cause: a word with two meanings, and no exception registered for it yet. Add one to PER_SET_OVERRIDES in script/generate-keywords.py, scoped to the specific mapping.json path — never change the global translations-en-fr.json entry to “fix” a single icon.

How the generator combines everything

For each icon, build_keywords() in script/generate-keywords.py does this, in order:

Full trace, on a real icon

glyphicons-v1/socials social-e-mail:

  1. Split: e-mail["e", "mail"]
  2. Translate: neither word is in the dictionary → nothing added yet
  3. No-separator join: more than one word → add "email"
  4. Merge overrides: keyword-overrides.json has "social social-e-mail": ["email", "courriel", "mail", "e-mail"] → merged in
  5. De-duplicate: "email" appeared from both step 3 and step 4 → kept once

Result: ["email", "courriel", "mail", "e-mail"]

Last updated on