How to Fix: `next/font`: Different when using Bodoni Moda font between `next/font/google` and Google Fonts
The Bodoni Moda mismatch between next/font/google and the version shown on Google Fonts usually comes from a variable-font axis difference, font file selection differences, or a stale cached font build in your Next.js app. The result is a font that looks heavier, narrower, or simply different even though the family name is the same.
Understanding the Root Cause
This issue happens because Next.js font optimization does not always behave exactly like the live preview on Google Fonts. With Bodoni Moda, the difference is especially noticeable because it is a variable font with visual behavior tied to axes such as weight and sometimes optical rendering characteristics. If your app imports the font with a different weight range, style, or subset than the Google Fonts preview uses, the rendered text can look different.
There are a few technical reasons behind this:
- Variable font axis selection: Google Fonts may preview a specific weight or axis configuration, while next/font/google can fetch a different variable configuration unless you define it clearly.
- Fallback font swapping: During development, a fallback font may render briefly or remain in some cases if configuration is incomplete, making the final result look inconsistent.
- Caching differences: Next.js caches optimized font assets. If you changed font configuration and still see the old result, your local build cache may be serving stale files.
- Subset or style mismatch: Importing only a subset or omitting the exact style and weight combination can change how the font appears.
- Browser rendering variance: Font smoothing and rendering differ slightly by browser and operating system, which becomes obvious with high-contrast serif fonts like Bodoni Moda.
In short, the bug is usually not that the font family is wrong. The problem is that the resolved font file and configuration used by Next.js is not identical to what you expected from Google Fonts.
Step-by-Step Solution
The safest fix is to define the font configuration explicitly, clear caches, and verify that the generated CSS is using the expected font weights and styles.
1. Import Bodoni Moda with explicit options
In your font setup file, avoid relying on vague defaults. Define subsets, weight, and display explicitly.
import { Bodoni_Moda } from 'next/font/google'
export const bodoniModa = Bodoni_Moda({
subsets: ['latin'],
weight: ['400', '500', '600', '700'],
style: ['normal', 'italic'],
display: 'swap',
variable: '--font-bodoni-moda'
})
Then apply it in your root layout:
import './globals.css'
import { bodoniModa } from './fonts'
export default function RootLayout({ children }) {
return (
<html lang="en" className={bodoniModa.variable}>
<body>{children}</body>
</html>
)
}
2. Use the generated variable or class correctly
If you imported the font as a CSS variable, make sure your styles actually reference it.
:root {
--font-serif-brand: var(--font-bodoni-moda);
}
.heading {
font-family: var(--font-serif-brand), serif;
font-weight: 400;
}
Or apply the generated class directly:
import { bodoniModa } from './fonts'
export default function Hero() {
return <h1 className={bodoniModa.className}>Elegant headline</h1>
}
3. Match the exact weight you expect
Many font mismatches are actually weight mismatches. If the Google Fonts preview looks lighter or more refined, inspect which weight it is using and set that exact value in your CSS.
.headline {
font-family: var(--font-bodoni-moda), serif;
font-weight: 400;
font-style: normal;
}
If you accidentally use 500 or 600, Bodoni Moda can look noticeably different.
4. Clear the Next.js cache
If you changed the import and the font still looks wrong, clear the build cache and restart the app.
rm -rf .next
npm run dev
Or with another package manager:
rm -rf .next
pnpm dev
This forces Next.js to regenerate optimized font assets.
5. Inspect the generated font CSS in the browser
Open DevTools and verify:
- The applied font-family is the one generated by next/font.
- The correct font-weight is active.
- No later CSS rule overrides the font.
- No component-level style replaces the font with a fallback serif stack.
6. If precision matters, test a local font fallback strategy
If you need pixel-level consistency and suspect a remote font file difference, you can compare against a local font setup using next/font/local.
import localFont from 'next/font/local'
export const bodoniLocal = localFont({
src: [
{
path: './fonts/BodoniModa-Regular.woff2',
weight: '400',
style: 'normal'
},
{
path: './fonts/BodoniModa-Italic.woff2',
weight: '400',
style: 'italic'
}
],
variable: '--font-bodoni-local'
})
This is useful when you want complete control over the exact font files being served.
7. Final recommended implementation
import { Bodoni_Moda } from 'next/font/google'
export const bodoniModa = Bodoni_Moda({
subsets: ['latin'],
weight: ['400', '700'],
style: ['normal', 'italic'],
display: 'swap',
variable: '--font-bodoni-moda'
})
import { bodoniModa } from './fonts'
import './globals.css'
export default function RootLayout({ children }) {
return (
<html lang="en" className={bodoniModa.variable}>
<body>{children}</body>
</html>
)
}
h1, h2, .brand-serif {
font-family: var(--font-bodoni-moda), serif;
font-weight: 400;
font-style: normal;
}
Common Edge Cases
- Development versus production differences: Development mode may show temporary rendering inconsistencies due to hot reloads or asset refresh timing. Always verify with a production build too.
- Font overridden by global CSS: A reset, theme provider, or component library may apply another serif family after your font class is attached.
- Incorrect Tailwind integration: If you map the CSS variable incorrectly in Tailwind CSS, the generated utility class may point to the wrong font family.
- Missing italic style: If your design uses italic text but you only imported normal style, the browser may synthesize italic rendering, which looks different from the real font.
- Subset mismatch: If your content includes characters outside the imported subset, the browser may fall back to another font for some glyphs.
- Cache persistence in deployment: Hosting or CDN layers may continue serving previous font assets after redeploying.
FAQ
Why does Bodoni Moda look different only in Next.js?
Because next/font/google optimizes and self-hosts the font based on your import configuration. If that configuration does not match the exact preview conditions from Google Fonts, the rendered result can differ.
Do I need to specify weights even for a variable font?
Yes. Even with a variable font, explicitly declaring the weights you use helps Next.js resolve the correct font assets and avoids accidental visual differences.
Is this a bug in Next.js or just expected behavior?
It can feel like a bug, but in many cases it is expected behavior caused by configuration differences, caching, or browser rendering. If the same explicit configuration still produces a different file or output, then it may indicate an issue in the font integration pipeline.
The practical fix is simple: define the font import explicitly, use the generated class or variable correctly, verify the applied weight, and clear the .next cache before testing again.