A Next.js Guide to Google and Local Fonts in shadcn/ui

A Next.js Guide to Google and Local Fonts in shadcn/ui

written byArmaan Chaand
17 May 20265 min read

When you kickstart a new shadcn/ui project for Next.js, the fonts you choose are pre-configured for Next.js and Tailwind CSS.

There's a chance you might want to change fonts later on or perhaps, use local fonts instead. That's what I want to cover in this guide.

Understanding NextJs Fonts

In short, NextJs gives you an easy to configure module to either use Google Fonts (for which you don't even need to import a stylesheet link, just knowing the name of the font is enough) or a local font.

Despite which method you choose, that myFont variable will contain two properties — variable and className. In a normal Next.js app, you might use the className property, but not in a shadcn/ui project.

To know more about font optimization, I recommend reading the official docs, which you may find here.

Next.js Fonts in a shadcn/ui Project

shadcn/ui projects use myFont.variable rather than myFont.className. This exposes the font as a CSS variable on the page, which Tailwind's config can then pick up and apply through the theme.

Google Fonts in shadcn/ui

To add or change a Google font in a shadcn/ui project, you first have to import the font helper function from next/font/google, just like the example above. Then choose a unique CSS variable name for this font. For example:

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

const  fontRoboto  =  Roboto({
	subsets: ['latin'],
	variable:  '--font-roboto' // Unique Variable
});

Since shadcn/ui applies fonts through Tailwind CSS, the font needs to be available as a CSS custom property on the page. This is done by applying myFont.variable to a top-level element (like <html> or <body>), so the CSS variable is inherited by all descendants in the tree and Tailwind can reference it through the @theme block.

export  default  function  RootLayout(...) {

return (
	<html
		lang="en"
		suppressHydrationWarning
		className={cn(fontRoboto.variable)} // Reference the variable
	>
		<body>
			<ThemeProvider>{children}</ThemeProvider>
		</body>
	</html>
)}

Now open global.css file and reference this custom property inside @theme inline block:

@theme inline {
	--font-sans: var(--font-sans);
	--font-heading: var(--font-roboto); /* New Font Variable */
	...
}

Tailwind generates the font-heading utility class from the --font-heading theme variable, making it available to apply to any element. If this is meant to be the default font for the page, then it's best to apply the class name to the <html> or <body> tag:

export  default  function  RootLayout(...) {

return (
	<html
		lang="en"
		suppressHydrationWarning
		className={cn(fontRoboto.variable, "font-heading")} // Apply the font
	>
		<body>
			<ThemeProvider>{children}</ThemeProvider>
		</body>
	</html>
)};

Local Fonts in shadcn/ui

Using a local font in a shadcn/ui project is similar to using Google Fonts, except you use the localFont function from Next.js instead:

import  localFont  from  "next/font/local";

const  fontLocal  =  localFont({
	src:  "./fonts/Panchang.otf", // Path to local font
	variable:  "--font-local" // Unique variable
});

The src property expects the correct path to the local font. Next.js will throw a build error if the file isn't found at the specified path. For example, if the font file is stored in /app/fonts/Panchang.otf:

localFont called insrc value
app/layout.tsx"./fonts/Panchang.otf"
app/about/layout.tsx"../fonts/Panchang.otf"

The src path should be relative to the file where localFont is called.

The rest of the process is similar to using the Google font:

Conclusion

Regardless of whether you're using a Google Font or a local font, the approach in a shadcn/ui project is the same: expose the font as a CSS custom property via myFont.variable, and let Tailwind reference it through the @theme block.

Last Modified: 17 May 2026 at 11:34 AM