Skip to content

Performance · Next.js (App Router)

How to stop web fonts blocking text in Next.js (App Router)

Without `font-display`, the browser hides the text while it waits for the font file — the flash of invisible text. On a slow connection that can be seconds of a blank-looking page that has already loaded everything it needs.

The fix for Next.js (App Router)

13x detects your framework from the response and hands you this version rather than the generic one — below 50% confidence it hedges and gives you the generic one instead.

next/font sets font-display: swap for you and self-hosts the files at build time, which removes the Google Fonts request entirely:

ts code
// app/layout.tsx
import { Inter } from "next/font/google";

const inter = Inter({
  subsets: ["latin"],
  display: "swap",
  // Generates a metric-matched fallback, so the swap causes no layout shift.
  adjustFontFallback: true,
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

If you are still loading fonts with a <link> to fonts.googleapis.com, switching to next/font removes a third-party connection, a render-blocking request, and this finding at once.

For a local file, next/font/local takes the same display option:

ts code
import localFont from "next/font/local";

const brand = localFont({
  src: "./brand.woff2",
  display: "swap",
});

On a different stack? The general version of this fix explains what 13x checks and why it matters, without assuming a framework.

Check your Next.js (App Router) site

113 deterministic checks against your live URL, in about 30 seconds. Framework detected from the response, so every fix comes back in the form your stack actually uses.

No signup. Results in 30 seconds.