DEV Community

Cover image for How to add font family in Next.js | The Modern Way
Abdullah Nasir
Abdullah Nasir

Posted on

How to add font family in Next.js | The Modern Way

For a long time, I struggled to find the "right" way to add custom fonts to a Next.js project. I searched through endless forums and saw different kinds of processes, like the old-fashioned way where you have to download the raw font files, manually move them into a public/fonts folder, and then write messy @font-face rules in your CSS. While that works, it's a headache. It bloats your project size, takes up extra space in your GitHub repo, and usually causes that annoying "flicker" (Layout Shift) where the text jumps around when the page loads.

But there is more simple way from the help you can do the same process in short

1. Initialize the Font

Instead of downloading files, we import the font directly from next/font/google. Next.js will automatically download the font files at build time and host them locally for you. This means no extra space is taken up in your source cod.

Open your app/layout.tsx and set it up outside the component:

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

const poppins = Poppins({
  subsets: ["latin"],
  weight: ["400", "600", "700"], 
  variable: "--font-poppins", 
  display: "swap", 
});
Enter fullscreen mode Exit fullscreen mode

2. Inject the Font into your Layout

Now, you need to "inject" that variable into your HTML so the rest of your app (and Tailwind) can see it.

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

Enter fullscreen mode Exit fullscreen mode

3. Connect to Tailwind CSS

Next.js provides the font data, but Tailwind needs a "name" to call it by. Open tailwind.config.ts and map a utility class to your new CSS variable.

import type { Config } from "tailwindcss";

const config: Config = {
  theme: {
    extend: {
      fontFamily: {
        poppins: ["var(--font-poppins)", "sans-serif"],
      },
    },
  },
};
export default config;
Enter fullscreen mode Exit fullscreen mode

Why this is better than the "Manual Download" method

  1. Zero Cumulative Layout Shift (CLS): In the old way, text would "jump" when the font finished loading. Next.js 16 automatically adjusts the size of the fallback font so the transition is invisible.

  2. Performance & Privacy: You get the speed of Google Fonts without actually making requests to Google’s servers. Everything is served from your own domain.

  3. Automatic Subsetting: If you only need English characters, Next.js strips out the unused characters from the font file. This can make your font files up to 70% smaller than the ones you download manually.

Now The Final Step the result

export default function Hero() {
  return (
    <h1 className="font-poppins font-bold text-3xl">
      High Performance, Zero Effort.
    </h1>
  );
}
Enter fullscreen mode Exit fullscreen mode

Found this helpful? Let’s build something together!

🚀 Connect with me on LinkedIn: Abdullah

📂 Check out my recent project: Tazakur

📧** Direct Inquiries**: (abdullahnasir.xee@gmail.com)

Top comments (0)