Skip to main content

Loading Fonts using theme.json

Since WordPress 5.9 it is possible to load typefaces via theme.json. Eventually the internal PHP API to register fonts will also become available to developers. But the mechanism in theme.json can be used already to make use of this new and improved font handling.

Why use theme.json for controlling font loading?

Using theme.json to handle the registration of fonts automatically makes sure the font files are properly enqueued everywhere in WordPress. It provides us with a simple API to control all aspects of how the font should get rendered and loaded. This also directly works for any iframed editors.

How to register local font files

Most of the time we want to load custom font files that we bundle with the theme itself on the server. This is for both performance and privacy reasons. We can avoid additional requests to external servers.

Each font family we want to load needs to get it's own entry in the settings.typography.fontFamilies array. Each entry consists of:

  • fontFamily - Font Family declaration like in css
  • name - Human readable Name of the font family
  • slug - Computer readable Name of the font family
  • fontFace - Array of the individual font faces

The fontFace itself is another array that houses each of the individual font faces of the family. So each font weight, style etc gets added here manually.

  • fontFamily - Name of the font family
  • fontWeight - Weight of the current font face
  • fontStyle - Style of the current font face
  • fontDisplay - Font Display of the current font face
  • src - Array of relative file paths to the individual font files of the current font face
{
"settings": {
"typography": {
"fontFamilies": [
{
"fontFamily": "FontName, sans-serif",
"name": "FontName",
"slug": "fontname",
"fontFace": [
{
"fontFamily": "FontName",
"fontWeight": "100",
"fontStyle": "normal",
"fontDisplay": "block",
"src": [
"file:./dist/fonts/fontname/fontname-thin.otf",
"file:./dist/fonts/fontname/fontname-thin.woff",
"file:./dist/fonts/fontname/fontname-thin.woff2"
]
},
...
]
}
]
}
}
}

The resulting output on the page will be an inline style tag with the various @font-face declarations:

<style id="wp-webfonts-inline-css" type="text/css">
@font-face {
font-family:FontName;
font-style:normal;
font-weight:100;
font-display:block;
src:local(FontName), url('/wp-content/themes/tenup-theme/dist/fonts/fontname/fontname-thin.woff2') format('woff2'), url('/wp-content/themes/tenup-theme/dist/fonts/fontname/fontname-thin.woff') format('woff'), url('/wp-content/themes/tenup-theme/dist/fonts/fontname/fontname-thin.otf') format('opentype');
}

...
</style>