The WordPress Web Fonts API Has Arrived

The journey toward a web fonts API in WordPress has been a rollercoaster of emotions for developers. After being punted from the WordPress 5.9 release, it was moved to the Gutenberg project, where it could be built alongside related features that relied on it.

The API has been merged into the Gutenberg plugin and should land in version 12.8. Theme authors who want to test it can clone the dev version of the plugin or download the nightly version from Gutenberg Times.

Jono Alderson opened the original ticket for a web fonts API in February 2019. However, it was not until late 2021 that it gained a mass of support and development. By most accounts, the API looked ready to ship with WordPress 5.9. However, it was put on hold by Andrew Ozz, one of the lead WordPress developers.

It was not a popular decision, but it may have been the best direction. The API was limited because it did not yet have theme.json support. Being only available through PHP meant that theme authors would have mostly been doing what they always have — rolling out their own solution. This was not the holdup for its unveiling, but it will likely be the API’s most common use case.

While many wanted to see this feature land in WordPress 5.9, the extra months have given it time to evolve into a cleaner API that integrates with the site and content editors.

Theme authors can now define font-face definitions alongside their corresponding families in theme.json files, and WordPress will automatically load the necessary @font-face CSS in the editor and on the front-end. I have tested this extensively and have not run into any problems.

The potential downside is that the feature only ships with support for a local provider, which means fonts must be bundled with the theme. A Google Fonts provider was part of the original implementation but was later removed.

Ozz goes into further details in an earlier ticket, but his recommendation was to drop Google Fonts support for now:

Add support only for local fonts for now. If WordPress decides to include support for the Google CDN later on, the implementation will have to consider web privacy laws and restrictions and be tied with an eventual User Consent API, etc.

Related article: German Court Fines Website Owner for Violating the GDPR by Using Google-Hosted Fonts

Ari Stathopoulos, one of the developers behind the web fonts API, explained that bundling a solution in core that writes the font files directly to the server would improve privacy:

Instead of removing it, maybe we could implement them properly, enforcing locally-hosted webfonts to improve performance & privacy? This way we’d be setting a good example, and we’d see a significant performance & privacy improvement in the WP ecosystem as themes & plugins that currently use Google-fonts, Adobe-fonts and whatnot will start to adopt the API.

For now, it looks like local fonts are officially supported, but theme and plugin authors must register custom providers. One fear with leaving out Google Fonts support is that there will be many competing solutions in the wild instead of one solid provider that everyone can rely on. The more developers build their own wheels, the more likely different implementations ship with bugs or security issues.

Automattic already has a draft patch for a Google provider for Jetpack. Assuming that gets pulled into the plugin, it will undoubtedly conflict with a theme down the road that registers its own google provider ID.

Only supporting local fonts could also create larger theme download sizes. For many themes, this should be a non-issue. One, two, or three font packages are reasonable. However, if global style variations become popular, we could see themes that ship dozens of fonts to cover multiple pre-packaged designs. That will quickly lead to bloated theme files and, combined with enough images, theme authors may hit the 10MB limit for submission to the directory. That feels a little like tomorrow’s problem, but it is something to begin thinking about today.

There are still some issues that need to be solved around the API. However, pushing it through this early in the WordPress 6.0 release cycle will give everyone time to test and help improve it.

Testing Bundled Fonts

There are two methods for registering web fonts with WordPress. For theme authors, the simplest solution is to define them via their theme.json files. This is the method that I will cover below since the file has been standard since WordPress 5.8. There is a PHP example in the pull request ticket.

The theme.json keys and values mostly correspond to the CSS @font-face rule. Theme authors should brush up on it if it has been a while since they have used it.

For testing, I registered three web fonts through my theme, and the following screenshot shows them in action in the editor:

Testing three web fonts.

Web fonts should be registered under settings.typography.fontFamily as part of a specific font family definition. The following is a copy of the code I am testing in one of my themes using the Cabin font:

{
"settings": {
"typography": {
"fontFamilies": [
{
"fontFamily": "\"Cabin\", sans-serif",
"slug": "primary",
"name": "Primary",
"fontFace": [
{
"fontFamily": "Cabin",
"fontWeight": "400 700",
"fontStyle": "normal",
"src": [ "file:./public/fonts/cabin/Cabin-VariableFont_wdth,wght.ttf" ]
},
{
"fontFamily": "Cabin",
"fontWeight": "400 700",
"fontStyle": "italic",
"src": [ "file:./public/fonts/cabin/Cabin-Italic-VariableFont_wdth,wght.ttf" ]
}
]
}
]
}
}
}

Note that file:./public/fonts/*.ttf is relative to the theme folder. Theme authors need to adjust this to fit their theme structure.