Next.js Tutorials · React Development Tips · Frontend Development

Add Custom Font in Nextjs 14: A Step-by-Step Guide

Sandipan Das
Sandipan Das · full-stack developer, Kolkata, IndiaPublished · Updated · 2 min read
Add Custom Font in Nextjs 14: A Step-by-Step Guide — cover image

Adding a custom font in Next.js 14 takes four steps: load it from next/font, expose it as a CSS variable on <body>, register that variable in Tailwind, then use the class. Next self-hosts the file, so there is no request to Google on load. Here is how I do it.

The step that makes this work is the CSS variable. Without one you can only use the font where you imported it. With it, the font reaches every component in the tree.

Step One: No @next/font Package to Install — Use the Built-in next/font

yarn add @next/font

There is nothing to install. On Next.js 14 the @next/font package has been removed in favour of the built-in next/font, so the import below is next/font/google. The command above is the old step from earlier versions; leave it out. If an older project still imports @next/font, the official codemod renames those imports to next/font for you.

Step Two: Integrate Fonts into Your Base Layout

Go to the layout file that wraps every page. Import your fonts there, and nowhere else:

import { Cinzel_Decorative, Playfair_Display } from "next/font/google";
const playfairDisplay = Playfair_Display({
  subsets: ["latin"],
  variable: "--font-playfairDisplay",
  // weight: ["400", "700", "500", "800", "900"],
});
const cinzelDecorative = Cinzel_Decorative({
  subsets: ["latin"],
  variable: "--font-cinzelDecorative",
  weight: ["400", "700", "900"],
});

Three things in that block decide what you ship:

  • subsets — only the character sets you need.
  • variable — the CSS custom property name. This is the line that makes the font reachable from Tailwind.
  • weight — only the weights you use. It is commented out on the first font and set on the second: a variable font can leave it off, a static font cannot.

Now put the variables on the body tag, so they cascade:

    <html lang="en"><body className={`${playfairDisplay.variable} ${cinzelDecorative.variable}`}>             
            {children}  
      </body></html>

Step Three: Extend Font Family in Tailwind CSS

Open your Tailwind config and extend the font family section:

// tailwind.config.js

extend: {
  fontFamily: {
    "playfairDisplay": 'var(--font-playfairDisplay)',
    "cinzelDecorative": 'var(--font-cinzelDecorative)',
  },
  // Other Tailwind CSS configurations...
},

This turns the variable into a class Tailwind recognises. Miss it and your class silently does nothing — no error, just the default font. That is why it is the first thing I check when a font refuses to show.

Step Four: Use the Custom Font in Next.js 14 Components

Now the class works anywhere:

<div className="col-span-12 lg:col-span-4 border shadow-xl group font-cinzelDecorative"> 
<!-- Your content goes here -->
</div>

That is the whole thing. What takes longer than people expect is choosing the fonts, not wiring them. Two families is usually right: one for headings, one for body.

If the font is not applying, check these before changing anything else:

  1. Is the variable string in the loader identical to the one in your Tailwind config? A typo fails silently.
  2. Are the variable classes on <body>, not an inner div?
  3. Did you import the font in a layout, rather than in the component using it?

Usually it is the first one.

Questions

Questions this post answers

Why is my custom font not applying in Next.js 14?

Usually the variable string in the loader is not identical to the one in your Tailwind config — a typo there fails silently, with no error and just the default font. After that, check the variable classes are on the body tag rather than an inner div, and that you imported the font in a layout rather than in the component using it.

Do I need to install the @next/font package?

On Next.js 14, no. The @next/font package has been removed in favour of the built-in next/font, so the import is next/font/google and there is nothing extra to install. If an older project still imports @next/font, the official codemod renames those imports to next/font for you.

Why expose the font as a CSS variable at all?

Without one you can only use the font where you imported it. With the variable on the body tag it cascades, so the font reaches every component in the tree and Tailwind can turn it into a class you can use anywhere.

Does using next/font send a request to Google on every load?

No. Next self-hosts the font file, so there is no request to Google when the page loads.

Share:X·LinkedIn·Email

Related

  • Article

    ISR in Next.js: The Perfect SEO & Performance Strategy

    ISR in Next.js came out of a project I was working on once — a dynamic blog where content was king. It had great design, engaging posts, and an audience hungry for fresh updates. But something wasn’t right. I noticed…

    · 3 min read · by Sandipan Das
  • Next.js Tutorials

    How I Made My Next.js App Resilient After Vercel's API Fetching Time Limits

    A few months ago I was working on a Next.js project for a client, well before Vercel's API fetching time limits became my problem. Everything was going smoothly — pages were loading fast, data arrived when it was supposed to,…

    · 5 min read · by Sandipan Das
  • Next.js Tutorials

    Fix typescript error: Unexpected any and empty object issues

    To fix typescript error messages on a new project, start here. Two ESLint errors show up on every fresh Next.js and TypeScript project: Unexpected any , and the warning that {} allows any non-nullish value. Both come from next/typescript .…

    · 2 min read · by Sandipan Das

If you'd rather not do it yourself

Everything above works. You just need the time for it.

Follow the steps and fix it yourself. Or send the site to the team and get on with your day.

900+ projects completed since 2017, from Kolkata, India.