Keywords & Translations
script/generate-keywords.py actually reads three files, not two:
| File | Role | Documented 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.json | Source of French words | This page |
keyword-overrides.json | Source of per-icon synonyms | This 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).
| File | Answers the question | Keyed 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.
| Word | Global meaning | Real meaning in… | File |
|---|---|---|---|
bin | trash (poubelle) | a .bin binary file | glyphicons-v1/filetypes/mapping.json |
log | login (connexion) | a .log file | glyphicons-v1/filetypes/mapping.json |
ticket | an event/parking ticket (billet) | a support ticket | phpc/frontend-favicons/ticket/mapping.json |
apple | the 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:
- Split:
e-mail→["e", "mail"] - Translate: neither word is in the dictionary → nothing added yet
- No-separator join: more than one word → add
"email" - Merge overrides:
keyword-overrides.jsonhas"social social-e-mail": ["email", "courriel", "mail", "e-mail"]→ merged in - De-duplicate:
"email"appeared from both step 3 and step 4 → kept once
Result: ["email", "courriel", "mail", "e-mail"]
Related pages
- Search in IconDropdown — how these
keywords.jsonfiles are actually used by the component - Adding New Icons — what to do (and what you can safely skip) when adding an icon