# Fixing Google Fonts in Next.js 13+: A Pixel-Perfect Guide

> Why CSS @import fails to load Google Fonts in Next.js 13+ and what to use instead: next/font/google in the root layout, font variables applied to the html element, and CSS updated to consume them.

Source: https://chanmeng.org/blog/nextjs-google-fonts-fix
Author: Chan Meng — https://chanmeng.org
Published: 2025-10-30
Tags: Frontend

---

*Originally published on LinkedIn, 30 October 2025. Republished here with light editing.*

Recently, while building a retro gaming website with Next.js, I ran into a frustrating issue: my pixel fonts weren't loading. Here's what I learned about the right way to handle Google Fonts in modern Next.js applications.

## The Problem

I was using CSS @import to load Google Fonts:

```css
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
```

Result? All fonts failed to load. The browser's document.fonts showed nothing. My pixel-art aesthetic was ruined.

## Why CSS @import Fails in Next.js

Next.js 13+ has a built-in font optimization system that doesn't play well with traditional CSS imports. Using @import:

- Bypasses Next.js optimizations
- Creates unnecessary external requests
- Can cause Flash of Unstyled Text (FOUT)
- May not load reliably during build

## The Solution: Use next/font/google

Here's the proper approach in 3 simple steps:

## Step 1: Import Fonts in app/layout.tsx

```css
import { Press_Start_2P, VT323, Pixelify_Sans } from "next/font/google";

const pressStart2P = Press_Start_2P({
  weight: "400",
  subsets: ["latin"],
  variable: "--font-press-start",
  display: "swap",
});

const vt323 = VT323({
  weight: "400",
  subsets: ["latin"],
  variable: "--font-vt323",
  display: "swap",
});
```

## Step 2: Apply Font Variables to HTML

```
export default function RootLayout({ children }) {
  return (
    <html className={`${pressStart2P.variable} ${vt323.variable}`}>
      <body className={pressStart2P.className}>
        {children}
      </body>
    </html>
  );
}
```

## Step 3: Update CSS to Use Variables

Remove the @import statements and use CSS variables instead:

```css
body {
  font-family: var(--font-press-start), 'Courier New', monospace;
}

.font-pixel-display {
  font-family: var(--font-press-start), 'Courier New', monospace;
}
```

Bonus: Update your Tailwind config for utility classes:

```
fontFamily: {
  'pixel-display': ['var(--font-press-start)', 'monospace'],
  'pixel-content': ['var(--font-vt323)', 'monospace'],
}
```

## Why This Works Better

✅ Self-hosted: Fonts are served from your domain, not Google's ✅ Zero layout shift: No flash of unstyled text ✅ Better performance: Automatic optimization and preloading ✅ Privacy-friendly: No external tracking ✅ Type-safe: TypeScript support out of the box

## Testing Your Fix

After implementing these changes:

1. Restart your dev server (important!)
2. Hard refresh your browser (Ctrl+Shift+R / Cmd+Shift+R)
3. Check DevTools: Inspect any text element and verify the computed font-family shows your custom font
4. Look for font files in the Network tab with status 200

## Troubleshooting

If fonts still don't appear:

```bash
# Clear Next.js cache
rm -rf .next
npm run dev
```

Then hard refresh your browser again.

## Key Takeaway

Don't use CSS @import for fonts in Next.js 13+. Always use next/font/google or next/font/local for optimal performance and reliability.

This approach transforms font loading from a potential bottleneck into a strength, giving you:

- Faster page loads
- Better user experience
- Zero configuration optimization

Resources:

- [Next.js Font Optimization Docs](https://nextjs.org/docs/app/building-your-application/optimizing/fonts)
- [next/font API Reference](https://nextjs.org/docs/app/api-reference/components/font)
