How to deal with fonts
Overview
Our fonts are optimized for size. At the moment there are 2 different fonts:
-
The "full" roman variable font, which contains a bunch of characters, but is already optimized from the "regular" Inter variable font: some characters and layout features that were unlikely to be used in our pages have been dropped.
-
The "subset" roman variable font, which contains limited characters and layout features. It should be enough for most pages in our "main" locales (en, de, fr, ru, es, pt, pl & it). All pages preload this subset through a regexp on
ServerHtml
which finds the font by name using a regular expression.
The subset should be preloaded on all pages, and the full font should only be used if there are characters on the page supported by the full font and not the subset. That should be pretty rare: because we've specified the unicode-range explicitly in the CSS, in Chinese or Japanese for instance, most pages should only load the subset (useful for english language content) and then fall back to a system font for the rest, since our font doesn't cover Chinese or Japanese characters.
Both fonts should only contain weights from 300 to 600 and only the "roman" font. We no longer have an italic font: browsers synthetize one or display italic text (which should be pretty rare on AMO) as normal text.
Prerequisites
To use the commands below, install https://github.com/fonttools/fonttools. This should give you a pyftsubset
command and some python libraries we need.
How to generate the full font
Run the following command:
./bin/regenerate_font.js "src/fonts/woff2/Inter-roman.var.woff2" "<unicode-range>"
Where <unicode-range>
is the full unicode range you want to support.
Under the hood, regenerate_font.js
will call pyftsubset
and save the new font to src/fonts/woff2/Inter-roman.var.woff2
, then regenerate the src/fonts/inter.scss
file as well as src/fonts/Inter-roman.var.html
file used to list all characters in the font.
How to generate the subset font
run the following command:
./bin/regenerate_font.js "src/fonts/woff2/Inter-roman-subset-en_de_fr_ru_es_pt_pl_it.var.woff2" "<unicode-range>"
Where <unicode-range>
is the full unicode range you want to support.
Under the hood, regenerate_font.js
will call pyftsubset
and save the new font to src/fonts/woff2/Inter-roman-subset-en_de_fr_ru_es_pt_pl_it.var.woff2
, then regenerate the src/fonts/inter-subset.scss
file as well as Inter-roman-subset-en_de_fr_ru_es_pt_pl_it.var.html
file used to list all characters in the font.
How to update the base font used by regenerate_font.js
Download the latest Inter-roman.var.woff2
from https://github.com/philipbelesky/inter-ui/tree/main/Inter%20(web), use something like https://github.com/source-foundry/Slice to only keep weights from 300 to 600 and save it as src/fonts/woff2/Inter-roman-reduced-weights.var.woff2
How to select the right unicode-range of a font
Finding the right unicode-range to use is a manual process using different tools:
-
Use https://github.com/zachleat/glyphhanger to check fonts used on our pages. Don't forget the
--family
argument, as the language dropdown on all our pages contain a bunch of extra characters that would otherwise be returned. Good pages to use are the homepage, about page, review guide, first page of each category, as well as the detail page of a few popular add-ons. -
Use https://character-table.netlify.app/ to check what characters are used by which language.
-
Use our
bin/find_characters_in_font.py
command to find the full unicode range supported by a font (It doesn't bother simplifying the range likeregenerate_font.js
does however)
A quick way to get the unicode code point value of a character is to look it up on a character table tool or use '<char>'.charCodeAt().toString(16)
. Don't forget the U+
prefix when specifying the range though!
How to check that it works locally
Use https://wakamaifondue.com/beta/ to check a particular font, ensuring that it has the correct layout features, characters and weights we want. You can compare the unicode-range
supported by the font to the one in the CSS, they should be the same. You can also check out the .html
file corresponding to each font (which regenerate_font.js
regenerates when it's called) to ensure the list of characters present match your expectations.
To test it, load the site locally, and check which fonts are downloaded. Repeat with a prod build to ensure that it works in production mode (webpack configuration is slightly special in production to ensure the name of the font is kept, with a suffix for the content hash).