Font Picker

<esp-font-picker> lets users browse and select from the full Google Fonts catalog. Font previews render in the dropdown using locally-served CSS files with base64-embedded font data, so no external requests are made at browse time.


How It Works

The font picker relies on two kinds of assets generated at build time by npm run build-fonts:

  1. font-definitions.json — A compact JSON catalog of every Google Font (family, category, variants, etc.). The component fetches this file once on first render to populate the dropdown.
  2. Individual CSS files — One <FontFamily>.css per font, each containing a @font-face rule with the preview weight base64-embedded. These are loaded on demand as the user scrolls through the list and unloaded when they scroll away.

Both assets live in the same directory (by default css/fonts/).


Serving Font Assets

After running npm run build-fonts, copy or serve the css/fonts/ directory from a public path. Then tell <esp-root> where to find it:

<esp-root font-css-root="/css/fonts/">
  <!-- your app -->
</esp-root>

The font-css-root attribute defaults to /css/fonts/ and must end with a trailing slash. The font picker constructs CSS URLs by family name (e.g. {font-css-root}Roboto.css), so these files must not be renamed or hashed by your build pipeline.

By default the picker also loads font-definitions.json from the same directory. If your asset pipeline hashes filenames for cache busting, you can point the JSON at a hashed URL separately:

<esp-root
  font-css-root="/css/fonts/"
  font-definitions-url="/dist/hashed-catalog.json">
</esp-root>

When font-definitions-url is set, the picker fetches from that URL instead of {font-css-root}font-definitions.json.


Basic Usage

<esp-root font-css-root="/css/fonts/">
  <esp-form-item label="Body font">
    <esp-font-picker></esp-font-picker>
  </esp-form-item>
</esp-root>

Category Filtering

Restrict the picker to a specific font category:

<esp-font-picker category="monospace"></esp-font-picker>

Supported categories: serif, sans-serif, display, handwriting, monospace, not-display (everything except display fonts).

Pre-selected Value

<esp-font-picker value="Roboto"></esp-font-picker>

Listening for Changes

const picker = document.querySelector("esp-font-picker");
picker.addEventListener("value-changed", (e) => {
  console.log("Selected font:", e.detail.family);
});

The value-changed event's detail contains the full GoogleFont object for the selected font.


Font & Weight Demo

This demo shows how to pair <esp-font-picker> with a weight picker to set page fonts and weights in real time. Select a font and weight below to see the sample text update.

The quick brown fox jumps over the lazy dog.

Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump! Sphinx of black quartz, judge my vow.


Keeping Fonts Updated

Google regularly adds new fonts to their catalog. To keep your local assets current:

Manual update:

npm run build-fonts

Automated (GitHub Actions): The repository includes a weekly workflow (.github/workflows/update-fonts.yml) that runs npm run build-fonts every Monday and opens a pull request if new fonts are detected. To use it, add a GOOGLE_FONTS_API_KEY secret to your repository (or rely on the built-in fallback key for open-source use).


Configuration Summary

Attribute / Property Element Description
font-css-root <esp-root> Path to the directory containing font CSS files. Must use stable (unhashed) filenames. Default: /css/fonts/
font-definitions-url <esp-root> Optional URL to font-definitions.json. When set, overrides the default {font-css-root}font-definitions.json path. Useful for cache-busted asset pipelines.
category <esp-font-picker> Filter fonts by category (serif, sans-serif, monospace, etc.)
value <esp-font-picker> The currently selected font family
placeholder <esp-font-picker> Placeholder text for the input. Default: "Choose a font..."

Where does this show?