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",
});
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>
);
}
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;
Why this is better than the "Manual Download" method
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.
Performance & Privacy: You get the speed of Google Fonts without actually making requests to Google’s servers. Everything is served from your own domain.
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>
);
}
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)