Identify the font and check its license. Load a Google font with next/font/google, or your own licensed files with next/font/local, and set the variable option so the font is exposed as a CSS variable. In Tailwind v4, map it in CSS with @theme inline { --font-sans: var(--font-inter); }. In Tailwind v3, add it to fontFamily in tailwind.config.js. Next.js self-hosts the files and generates a metric-adjusted fallback font for you.
Identify the font and where it comes from
You saw a site with type you want in your own project. As a developer you already have the tool to name it. In Chrome, Edge or Brave, right-click the text and choose Inspect, open the Computed tab and read font-family, font-weight, font-size, line-height and letter-spacing. Then scroll to the bottom of the Computed tab. The Rendered Fonts section names the font the browser is actually drawing, which is the one that matters when the declared stack has several names.
Next, open the Network panel, filter by Font and reload. The host of each font file decides which loader you will use later.
| Font files load from | What it means | Your route in Next.js |
|---|---|---|
fonts.gstatic.com | Google Fonts. Open source. | next/font/google |
| The site’s own domain or its CDN | Self-hosted. Could be an open font or a commercial one. | Check the license, get your own files, then next/font/local |
use.typekit.net | Adobe Fonts, served through the owner’s Adobe plan. | Adobe’s own embed code from your Adobe account. These files are not yours to self-host, so next/font does not apply. |
The faster route: click the text
With Font Inspector, press Alt + Shift + F (Option + Shift + F on Mac) and click the text. The panel shows the family, the font actually rendered, the source (Google Fonts, Adobe Fonts, self-hosted or system), the weight, the size in px, em and rem, the line height in px and as a ratio, the letter spacing, and any variable font axes or OpenType features the page uses. Fonts on this page lists every family with its weights and sizes, which is the list of weights you will load. The manual method is covered in depth in how to find a font with Chrome DevTools.
Get the font, the weights and the numbers in one pass.
Font Inspector names the font on any live text, labels its source, and copies the whole text style as CSS, Tailwind classes or SCSS variables. Free, no account.
License it before you write any code
Finding a font does not license it. Google Fonts are open source and fine for commercial projects, as explained in are Google Fonts free for commercial use?. A commercial typeface needs a web font license from the foundry or a reseller, and the purchase gives you the .woff2 files you will put in your repository. Do not copy the files from the other site’s server. They are easy to reach, and they are still covered by someone else’s license. The longer version is in font licensing explained.
If the original is out of budget, Font Inspector’s Get this font section suggests free Google Fonts look-alikes for popular paid fonts, and our free alternatives pages list them by font. They are similar, not identical, so test one with your real headlines.
Load a Google font with next/font/google
Import the family as a function from next/font/google. Names with spaces use an underscore, so Roboto Mono becomes Roboto_Mono. Set variable to the name of the CSS variable you want, and put the generated class on the html element. The examples use the App Router. The same loaders work in the Pages Router, where you apply them in pages/_app.
// app/layout.tsx
import { Inter, Fraunces } from "next/font/google";
import "./globals.css";
// Variable fonts need no weight option
const inter = Inter({
subsets: ["latin"],
display: "swap",
variable: "--font-inter",
});
const fraunces = Fraunces({
subsets: ["latin"],
display: "swap",
variable: "--font-fraunces",
});
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" className={`${inter.variable} ${fraunces.variable}`}>
<body className="font-sans antialiased">{children}</body>
</html>
);
}inter.variable is a class name that defines --font-inter. Nothing uses the font yet. That is Tailwind’s job in the next step.If the family is not a variable font, the Next.js docs say you must specify the weights, for example weight: ['400', '700'], and you can add style: ['normal', 'italic']. Load only the weights you saw on the site. Every extra weight of a static family is another file.
Despite the import name, the browser never talks to Google. According to the Next.js documentation, the CSS and font files are downloaded at build time and self-hosted with the rest of your static assets, and no requests are sent to Google by the browser. That also settles the privacy question described in Google Fonts, GDPR and self-hosting.
Load licensed files with next/font/local
For a font you bought, or an open font you downloaded, use next/font/local. Put the .woff2 files in your project, for example in app/fonts. The src path is relative to the file where you call the loader.
// app/layout.tsx
import localFont from "next/font/local";
// One variable font file
const brandSans = localFont({
src: "./fonts/BrandSans-Variable.woff2",
weight: "100 900",
display: "swap",
variable: "--font-brand-sans",
});
// Or several static files in one family
const brandSerif = localFont({
src: [
{ path: "./fonts/BrandSerif-Regular.woff2", weight: "400", style: "normal" },
{ path: "./fonts/BrandSerif-Italic.woff2", weight: "400", style: "italic" },
{ path: "./fonts/BrandSerif-Bold.woff2", weight: "700", style: "normal" },
],
display: "swap",
variable: "--font-brand-serif",
adjustFontFallback: "Times New Roman",
});brandSans.variable and brandSerif.variable to the html element exactly as in the Google example.Call each loader once and reuse the result. The Next.js docs note that every call hosts the font as one instance in your application, so if several files need the same font, export it from a single fonts.ts file and import it where needed. If you are not on Next.js, the plain CSS equivalent is an @font-face rule, which our @font-face generator writes for you.
Wire the CSS variable into Tailwind
The loader gave you --font-inter. Tailwind needs to know that font-sans should use it. How you say that depends on the Tailwind version.
Tailwind v4: @theme in your CSS
/* app/globals.css */
@import "tailwindcss";
@theme inline {
--font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
--font-display: var(--font-fraunces), ui-serif, Georgia, serif;
}--font-sans overrides the default sans stack. --font-display creates a new font-display utility.In v4, every variable in the --font-* namespace becomes a font family utility. The inline keyword matters here. Tailwind’s docs explain that when a theme variable references another variable, inline makes the utility use the value itself, so var(--font-inter) resolves on the element where the class is used and not higher up the tree where it may be undefined.
Tailwind v3: fontFamily in the config
// tailwind.config.js
const defaultTheme = require("tailwindcss/defaultTheme");
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
fontFamily: {
sans: ["var(--font-inter)", ...defaultTheme.fontFamily.sans],
display: ["var(--font-fraunces)", ...defaultTheme.fontFamily.serif],
},
},
},
plugins: [],
};Either way, you now write font-sans and font-display in your markup. Putting font-sans on the body, as in the layout above, makes it the default for the whole app. For more on choosing what comes after your font in the stack, see font stacks and fallbacks or build one with the font stack builder.
Copy the sizes and spacing from the live site
The family alone will not reproduce the look. The heading you admired is a combination of size, weight, line height and tracking. In Font Inspector, inspect that heading and copy the style as Tailwind classes, then paste it into your component. Do the same for body text and one small style. The details are in copy typography as CSS or Tailwind.
Tailwind’s arbitrary values accept exact numbers, which is handy for a first pass. A heading that measures 56px with a 1.1 line height and -0.02em tracking can be written like this.
<h1 class="font-display text-[56px] leading-[1.1] tracking-[-0.02em] font-semibold">
Type that feels right
</h1>Once a value shows up more than twice, give it a name. In v4 that is another theme variable. In v3, add the same values under fontSize and letterSpacing in the config.
@theme {
--text-hero: 3.5rem;
--text-hero--line-height: 1.1;
--tracking-hero: -0.02em;
}
/* Now: class="font-display text-hero tracking-hero" */--line-height suffix sets the default line height for that text size.Prefer rem for sizes so the text respects the reader’s browser settings. The px to rem converter does the division. If the site scales its headings between mobile and desktop, measure both and let the fluid typography tool write a clamp() value that connects them.
What next/font handles for you
A web font arrives after the first paint. Until then the browser shows a fallback, and when the real font swaps in, lines can rewrap and the page can jump. Fixing that by hand means writing a second @font-face for a local font with size-adjust and the ascent and descent overrides tuned to your web font. With next/font you usually skip that work.
- Automatic fallback font. The
adjustFontFallbackoption controls whether an automatic fallback font is used to reduce layout shift. Fornext/font/googleit is a boolean and defaults totrue. Fornext/font/localit defaults to'Arial', and you can set'Times New Roman'for a serif orfalseto turn it off. - font-display. The
displayoption defaults toswap, so text is visible while the font loads. - Preloading.
preloaddefaults totrue. A font loaded in the root layout is preloaded on all routes, and a font loaded in a single page only on that route. For Google fonts, list thesubsetsyou need so the right file is preloaded. - Self-hosting. Files are served from your own domain with the rest of your static assets.
When you deploy, run the same check on your own site that you ran on the original. Inspect a heading and confirm that the rendered font is your web font and not the fallback. A typo in a variable name fails silently: the page falls through to the system stack and nobody notices for weeks. Font Inspector flags a fallback when the declared font is not the one being drawn, and the website font checker lists what a public URL loads.
Questions & answers
How do I add a custom font to Next.js with Tailwind?+
Load the font with next/font/google or next/font/local, set the variable option, and add the generated variable class to the html element. Then map the CSS variable to a font utility: @theme inline with --font-sans in Tailwind v4, or theme.extend.fontFamily in Tailwind v3.
Does next/font/google send requests to Google?+
No. The Next.js documentation says the CSS and font files are downloaded at build time and self-hosted with your static assets, and no requests are sent to Google by the browser.
Why use @theme inline for fonts in Tailwind v4?+
Because the theme variable references another CSS variable. With inline, the utility uses the value directly, so var(--font-inter) resolves on the element where you use the class and not where the theme variable was defined.
Can I use an Adobe Fonts typeface with next/font?+
No. next/font works with Google Fonts and with font files you host yourself. Adobe Fonts are served from Adobe’s servers through the embed code of your own Adobe account.
Do I need to set a weight in next/font/google?+
Only for fonts that are not variable. The Next.js docs say a weight is required when the font is not a variable font, and that it can be a single string or an array such as 400 and 700.
Related free tools: PX to REM converter · Fluid typography clamp() calculator · @font-face generator · CSS font stack builder
See it on real sites: What font does Airbnb use? · What font does GitHub use? · What font does Notion use? · What font does Spotify use?
Sources and further reading: Next.js documentation: Font Module ↗ · Tailwind CSS documentation: font-family ↗ · Tailwind CSS documentation: Theme variables ↗ · Tailwind CSS v3 documentation: Font Family ↗ · MDN: size-adjust ↗ · MDN: font-display ↗