Optimizing Web Fonts in Next.js 13

Optimizing Web Fonts in Next.js 13

Web fonts are an essential aspect of modern web design. They allow for beautiful typography on the web, unique to your product ✨

1. What is FOUT and FOIT

You navigate to a website that initially displays a default font, such as Times New Roman or Arial, until the web font has been downloaded and installed. It then quickly switches the font from the default to the web font, often causing layout shift.

The layout shift can range from just moving a couple of pixels to a major shift caused by large fonts, or by different line break positions.

This phenomenon is called Flash Of Unstyled Text (FOUT). If the web font takes a long time to download, the user may see the text on the page "flash" or change from the default font to the web font.

In other cases, you may not see any text until the web font has been downloaded.

This is called Flash Of Invisible Text (FOIT), in which case the browser draws an invisible fallback font. This happens when the font-display CSS property is set to block.

For more reference about FOUT and FOIT, you can read this article:


2. Optimizing Web Fonts in Next.js 13 using @next/font module

Adding preconnect and font-face descriptors can improve the performance of fonts on your website by speeding up their loading time and defining their characteristics. However, manually adding these optimizations can be tedious and prone to errors. Ideally, we want our fonts to be optimized automatically.

This is where the @next/font module comes in. This module was introduced in Next.js 13 and allows you to easily add local and Google fonts to your website without worrying about the details of optimization.

The @next/font module makes it much easier to work with local and web fonts by automatically:

  • Downloading the web font at build time and serving it locally

  • Adding a fallback font and automatically adjusting its measurements to resemble the chosen web font as closely as possible.

You can use it by importing a font from the @next/font module and using the font instance to apply it to specific components in your website.

import { Poppins } from "@next/font/google";

const poppins = Poppins({ weight: "600", subsets: ["latin"] });

export default function Title() {  
    return <h1 className={poppins.className}>The Acme Blog</h1>;

Self-hosting Fonts

At build time, the @next/font module downloads both the font stylesheet from fonts.googleapis.com, and the font files defined in the @font-face src's that was previously fetched.

The fonts are now available locally, without requiring any external requests.

Automatic Matching Fallback

The @next/font module not only lets you serve fonts from your own domain, but it also automatically provides a custom fallback font that closely matches the intended web font, and even calculates the necessary measurements such as size-adjust, ascent-override, descent-override and lineheight-override to make the fallback font closely match the web font.

When using the @next/font module to display text on your website, you'll likely experience little to no layout shift when the font is changed.


The @next/font module also automatically preloads fonts when a subset has been defined. This can help both performance and user experience.

A preloaded font is downloaded as soon as possible, typically before the browser starts rendering the page. This avoids the potential for the font to render incorrectly or change while the page is loading, creating a seamless experience.

3. Conclusion

Using web fonts can be challenging due to issues like FOUT and FOIT. However, with some optimizations like adding preconnect and using font-face descriptors like size-adjust, ascent-override, descent-override, and lineheight-override, you can improve the performance and appearance of your web fonts.

The @next/font module makes working with web fonts significantly easier by automatically implementing these optimizations and serving the fonts from your own domain.