WordPress Font Library
WordPress 6.5 introduced a font library which allows themes and plugins to define custom font stacks which reference either:
- native system fonts,
- font files bundled with themes and plugins,
- externally hosted fonts (such as Google Fonts).
Users can then use those fonts in the style editor of the block themes:

When using either locally hosted or externally hosted fonts, WordPress uses the wp_head
action with a callback to wp_print_font_faces()
to add the font definitions:
add_action( 'wp_head', 'wp_print_font_faces', 50 );
which prints the following CSS with @font-face
definitions in the <head>
:
<style id="wp-fonts-local">
@font-face{font-family:Inter;font-style:normal;font-weight:300 900;font-display:block;src:url('https://example.com/wp-content/themes/twentytwentyfour/assets/fonts/inter/Inter-VariableFont_slnt,wght.woff2') format('woff2');font-stretch:normal;}
</style>
All other stylesheets can then reference the font by name which is “Inter” in this example.
The inline font definitions produced by wp_print_font_faces()
point to font URLs which are a critical resource that must be loaded as soon as possible to avoid layout shift and to speed up the First Contentful Paint (FCP) and the Largest Contenful Paint (LCP) when used for prominent headings or menus.
Here is a comparison between the default behaviour and with the preload enabled:

Notice how the preloaded version has an extra font because it doesn’t know that the particular style isn’t used on the page.
How to Preload Custom Fonts?
Here is a snippet of PHP to add preload hints for the fonts to the <head>
to ensure they’re loaded as early as possible:
function your_prefix_preload_theme_fonts() {
// This is available only since WP 6.4.
$fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json();
if ( empty( $fonts ) ) {
return;
}
$srcs = wp_list_pluck( $fonts[0], 'src' );
$srcs = array_filter( array_merge( ...$srcs ) ); // Flatten them.
$preload = array_map(
function ( $src ) {
return sprintf(
'<link rel="preload" href="%s" as="font" type="font/%s" crossorigin />',
esc_url( $src ),
esc_attr( pathinfo( $src, PATHINFO_EXTENSION ) )
);
},
$srcs
);
echo implode( PHP_EOL, $preload );
}
add_action( 'wp_head', 'your_prefix_preload_theme_fonts', 6 ); // Add early in the <head>.
Limitations of Preloading
Please consider the preloading limitations when using this approach:
- Fonts or their specific styles and weights might not be used on all requests (like the example above) which is not desired.
- Fonts can have multiple format types and the browsers decide which one to use. Preloading different formats of the same font is too excessive.
- Preloading is not aware of the
unicode-range
filtering applied during the@font-face
definition so it will fetch the whole file instead of just the required characters.
Leave a Reply