A shadcn/ui theme sets three font variables: --font-sans, --font-serif and --font-mono. They feed Tailwind's font-sans, font-serif and font-mono utilities, and font-sans is applied to the whole page. A theme only names a font, though. You still need to load it.
In Next.js: use next/font
next/font self-hosts Google Fonts, removes layout shift and needs no external requests. Load the font into its own variable, then point the theme variable at it:
import { Inter, JetBrains_Mono } from "next/font/google"
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" })
const mono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-jetbrains" })
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={`${inter.variable} ${mono.variable}`}>
<body>{children}</body>
</html>
)
}
:root {
--font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
--font-mono: var(--font-jetbrains), ui-monospace, monospace;
}
Avoid loading the font straight into --font-sans. If your theme also sets --font-sans in :root, whichever rule
comes last wins, and you may silently get the fallback font. A dedicated variable like --font-inter sidesteps the
conflict.
In Vite and other setups: a stylesheet
Add the Google Fonts stylesheet to your index.html (or @import it at the top of your CSS), then reference the family by name:
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
:root {
--font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
}
Fontsource packages such as @fontsource-variable/inter are a good self-hosted alternative.
Letter spacing
Some themes also set --tracking-normal (exported as letter spacing). Tight geometric fonts often look better at -0.01em; wide monospace fonts sometimes want 0. Apply it to the body with letter-spacing: var(--tracking-normal), which themes from this site include automatically.
Pairing fonts
- One sans for everything (Inter, Geist, Outfit, DM Sans) is the safe, modern default.
- A serif for headings (Playfair Display, Fraunces, Instrument Serif) gives an editorial feel. Set it on headings with
font-serif. - A monospace for the whole UI (JetBrains Mono, Space Mono) reads as terminal or developer-tool.
Browse themes by typeface: Inter, Geist, serif and monospace. Or try any Google Font live in the editor's Type panel.