OWolf

BlogToolsProjectsAboutContact
© 2025 owolf.com
HomeAboutNotesContactPrivacy

2025-05-31 Web Development, Design

How to Use Custom Fonts in a Next.js 15 + Tailwind 4 App

By O. Wolfson

Tailwind CSS v4 introduces a more design-token–oriented approach to theming, and eliminates the tailwind.config.ts configuration file. If you’re building a modern app with Next.js 15 and want to use custom fonts like IBM Plex Sans and IBM Plex Mono, here’s how to do it using just next/font/google and inline design tokens.


What We’ll Build

  • A Next.js 15 app with Tailwind v4
  • IBM Plex Sans and Mono as the global font family
  • A token-based approach using @theme inline
  • No tailwind.config.ts required

Step-by-Step Setup

1. Install Tailwind CSS v4

If you haven't already:

bash
npm install -D tailwindcss@^4

Make sure you're using Tailwind v4 (not v3). You can confirm with:

bash
npx tailwindcss --version

2. Import Fonts Using next/font/google

In your src/app/layout.tsx:

tsx
import { IBM_Plex_Sans, IBM_Plex_Mono } from "next/font/google";

const plexSans = IBM_Plex_Sans({
  variable: "--font-sans",
  subsets: ["latin"],
  weight: ["400", "500", "600", "700"],
  display: "swap",
});

const plexMono = IBM_Plex_Mono({
  variable: "--font-mono",
  subsets: ["latin"],
  weight: ["400", "500", "600", "700"],
  display: "swap",
});

Then apply the CSS variables to the <body>:

tsx
<body
  className={`${plexSans.variable} ${plexMono.variable} font-main antialiased`}
>

This attaches the CSS variables (--font-sans, --font-mono) to your HTML context.


3. Define Your Font Tokens in globals.css

Tailwind 4 supports theming with @theme inline. Open or create globals.css and add:

css
@import "tailwindcss";
@import "tw-animate-css"; /* Optional */

@theme inline {
  --font-sans: var(--font-sans); /* From next/font/google */
  --font-mono: var(--font-mono);
  --font-main: var(--font-sans); /* Token for the main font */
}

This defines --font-main so that you can use it via Tailwind class utilities.


4. Apply Your Font Globally

Still inside globals.css, define the base styles:

css
@layer base {
  body {
    @apply font-main bg-background text-foreground;
  }
}

This ensures your IBM Plex font is used globally across the site.


5. Use in Components

Anywhere in your app, you can now use:

tsx
<p className="font-main text-xl">This text uses IBM Plex Sans.</p>
<code className="font-mono">console.log("IBM Plex Mono")</code>

Why This Works

Tailwind v4 encourages using design tokens (CSS variables) over hardcoded values or complex config files. By combining this with Next.js’s native font optimization via next/font/google, you get:

  • No tailwind.config.ts required
  • Fonts load only when used
  • CSS variables make theming and switching easy

Bonus Tip: Light & Dark Theme Fonts?

You can define different fonts for light/dark mode using the .dark selector in your theme:

css
.dark {
  --font-main: var(--font-mono);
}

Then font-main will automatically switch based on theme context.


Recap

StepDescription
next/font/googleLoads IBM Plex and sets CSS variables
layout.tsxApplies font variable classes to <body>
@theme inlineMaps --font-main to your desired font
font-main utilityUsed just like Tailwind classes

Result

You now have a clean, modern font setup that’s fully compatible with Next.js 15, Tailwind CSS v4, and scalable design token systems.

Shoutout to Tuomo Kankaanpää for the video that inspired this guide.