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.
- To use Google Font, you do this:
import { Roboto } from "next/font/google"; const myFont = Roboto({ weight: 'variable', subsets: ['latin'], variable: "--font-roboto" }) - And for local fonts, you first have to specify the path to the font and then use the
localFontfunction from the modulenext/font. For example,import localFont from 'next/font/local'; const myFont = localFont({ src: './local-roboto-font.woff2', variable: "--font-local" })
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 in | src value |
|---|---|
app/layout.tsx | "./fonts/Panchang.otf" |
app/about/layout.tsx | "../fonts/Panchang.otf" |
The
srcpath should be relative to the file wherelocalFontis called.
The rest of the process is similar to using the Google font:
-
Apply
myFont.variableto a top-level element (like<html>or<body>)export default function RootLayout(...) { return ( <html lang="en" suppressHydrationWarning className={cn(fontLocal.variable)} // Reference the variable. > <body> <ThemeProvider>{children}</ThemeProvider> </body> </html> )}; -
Reference this variable inside
@theme inlineblock@theme inline { --font-panchang: var(--font-local); /* Local Font */ ... } -
The font is now available via the Tailwind utility class (e.g.
font-panchang).
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
