Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cloudflare/vinext/llms.txt

Use this file to discover all available pages before exploring further.

The next/font module provides automatic font optimization with zero layout shift, reduced network requests, and built-in subsetting.

Google Fonts

Import fonts from Google Fonts CDN (dev) or self-host them (production).

Import

import { Inter, Roboto_Mono } from 'next/font/google'

Basic Usage

import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export default function Layout({ children }) {
  return (
    <html className={inter.className}>
      <body>{children}</body>
    </html>
  )
}

API Reference

subsets
string[]
required
Font subsets to load (reduces file size).Common subsets:
  • 'latin' — Latin alphabet (English, French, German, etc.)
  • 'latin-ext' — Extended Latin (Eastern European)
  • 'cyrillic' — Cyrillic alphabet (Russian, Ukrainian, etc.)
  • 'greek' — Greek alphabet
  • 'vietnamese' — Vietnamese
const inter = Inter({ 
  subsets: ['latin', 'latin-ext'] 
})
weight
string | string[]
Font weights to load.
// Single weight
const inter = Inter({ subsets: ['latin'], weight: '400' })

// Multiple weights
const inter = Inter({ subsets: ['latin'], weight: ['400', '700'] })

// Variable font (all weights)
const inter = Inter({ subsets: ['latin'] })  // Loads 100-900
style
string | string[]
default:"'normal'"
Font styles to load.
const inter = Inter({ subsets: ['latin'], style: ['normal', 'italic'] })
display
string
default:"'swap'"
CSS font-display value.
  • 'swap' — Show fallback immediately, swap when loaded (recommended)
  • 'optional' — Use font if cached, otherwise use fallback
  • 'fallback' — Brief block period, then swap
  • 'block' — Block rendering until font loads (avoid)
const inter = Inter({ subsets: ['latin'], display: 'optional' })
preload
boolean
default:"true"
Add <link rel="preload"> for faster loading.
const inter = Inter({ subsets: ['latin'], preload: true })
fallback
string[]
default:"['sans-serif']"
Fallback fonts when the web font is loading or unavailable.
const inter = Inter({ 
  subsets: ['latin'],
  fallback: ['system-ui', 'arial', 'sans-serif']
})
adjustFontFallback
boolean
default:"true"
Automatically adjust fallback fonts to reduce layout shift.
const inter = Inter({ subsets: ['latin'], adjustFontFallback: false })
variable
string
CSS variable name for the font.
const inter = Inter({ 
  subsets: ['latin'],
  variable: '--font-inter'
})

// Usage in CSS:
// font-family: var(--font-inter);

Return Value

className
string
CSS class name that applies the font.
const inter = Inter({ subsets: ['latin'] })

<div className={inter.className}>
  This text uses Inter
</div>
style
{ fontFamily: string }
Inline style object with fontFamily.
<div style={inter.style}>
  This text uses Inter
</div>
variable
string
CSS class name that sets the CSS variable.
const inter = Inter({ subsets: ['latin'], variable: '--font-inter' })

<html className={inter.variable}>
  {/* Now var(--font-inter) is available everywhere */}
</html>

Examples

Multiple Fonts

import { Inter, Roboto_Mono } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })
const robotoMono = Roboto_Mono({ subsets: ['latin'] })

export default function Layout({ children }) {
  return (
    <html className={`${inter.variable} ${robotoMono.variable}`}>
      <body className={inter.className}>{children}</body>
    </html>
  )
}

With Tailwind CSS

// app/layout.tsx
import { Inter } from 'next/font/google'

const inter = Inter({ 
  subsets: ['latin'],
  variable: '--font-inter'
})

export default function RootLayout({ children }) {
  return (
    <html className={inter.variable}>
      <body>{children}</body>
    </html>
  )
}
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-inter)', 'sans-serif'],
      },
    },
  },
}

Single Page

import { Playfair_Display } from 'next/font/google'

const playfair = Playfair_Display({ subsets: ['latin'] })

export default function ArticlePage() {
  return (
    <article className={playfair.className}>
      <h1>Beautiful Typography</h1>
      <p>Using Playfair Display</p>
    </article>
  )
}

Local Fonts

Use fonts from local files.

Import

import localFont from 'next/font/local'

Basic Usage

import localFont from 'next/font/local'

const myFont = localFont({
  src: './fonts/my-font.woff2'
})

export default function Layout({ children }) {
  return (
    <html className={myFont.className}>
      <body>{children}</body>
    </html>
  )
}

API Reference

src
string | LocalFontSrc | LocalFontSrc[]
required
Font file path(s).Single file:
const myFont = localFont({
  src: './fonts/my-font.woff2'
})
Multiple weights:
const myFont = localFont({
  src: [
    {
      path: './fonts/my-font-regular.woff2',
      weight: '400',
      style: 'normal',
    },
    {
      path: './fonts/my-font-bold.woff2',
      weight: '700',
      style: 'normal',
    },
  ]
})
weight
string
Default font weight (when using single src string).
const myFont = localFont({
  src: './fonts/my-font.woff2',
  weight: '600'
})
style
string
default:"'normal'"
Default font style.
const myFont = localFont({
  src: './fonts/my-font-italic.woff2',
  style: 'italic'
})
display
string
default:"'swap'"
CSS font-display value (same as Google Fonts).
fallback
string[]
Fallback fonts.
const myFont = localFont({
  src: './fonts/my-font.woff2',
  fallback: ['system-ui', 'sans-serif']
})
variable
string
CSS variable name.
const myFont = localFont({
  src: './fonts/my-font.woff2',
  variable: '--font-custom'
})
preload
boolean
default:"true"
Add preload hint.
declarations
Array<{ prop: string; value: string }>
Custom CSS properties for the @font-face rule.
const myFont = localFont({
  src: './fonts/my-font.woff2',
  declarations: [
    { prop: 'font-feature-settings', value: '"liga" 1' },
    { prop: 'font-variation-settings', value: '"wght" 400' }
  ]
})

Examples

Variable Font

import localFont from 'next/font/local'

const myFont = localFont({
  src: './fonts/my-variable-font.woff2',
  variable: '--font-custom'
})

export default function Layout({ children }) {
  return (
    <html className={myFont.variable}>
      <body className={myFont.className}>{children}</body>
    </html>
  )
}

Multiple Weights and Styles

import localFont from 'next/font/local'

const myFont = localFont({
  src: [
    {
      path: './fonts/my-font-light.woff2',
      weight: '300',
      style: 'normal',
    },
    {
      path: './fonts/my-font-regular.woff2',
      weight: '400',
      style: 'normal',
    },
    {
      path: './fonts/my-font-regular-italic.woff2',
      weight: '400',
      style: 'italic',
    },
    {
      path: './fonts/my-font-bold.woff2',
      weight: '700',
      style: 'normal',
    },
  ]
})

export default function Layout({ children }) {
  return (
    <html className={myFont.className}>
      <body>{children}</body>
    </html>
  )
}

Self-Hosting Google Fonts

In production builds, vinext automatically downloads and self-hosts Google Fonts:
  1. Build time: Plugin fetches font CSS and .woff2 files from Google
  2. Assets: Fonts are bundled with your app
  3. Runtime: No requests to Google Fonts CDN
Benefits:
  • Faster loading (no DNS lookup, no third-party request)
  • Better privacy (no data sent to Google)
  • Works offline
Dev mode: Fonts load from Google CDN (faster iteration).

Performance

Zero Layout Shift

vine automatically generates fallback font metrics to prevent layout shift:
/* Generated by vinext */
@font-face {
  font-family: '__Inter_Fallback';
  src: local('Arial');
  ascent-override: 90.2%;
  descent-override: 22.4%;
  line-gap-override: 0%;
  size-adjust: 107.4%;
}

Subsetting

Loading only the characters you need:
const inter = Inter({ 
  subsets: ['latin'],  // Only Latin characters
})

// File size: ~30KB instead of ~120KB (all subsets)

Preloading

Preload hints ensure fonts load early:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin />

CSS Variables

Use CSS variables for flexible theming:
// app/layout.tsx
import { Inter, Roboto_Mono } from 'next/font/google'

const inter = Inter({ subsets: ['latin'], variable: '--font-sans' })
const robotoMono = Roboto_Mono({ subsets: ['latin'], variable: '--font-mono' })

export default function RootLayout({ children }) {
  return (
    <html className={`${inter.variable} ${robotoMono.variable}`}>
      <body>{children}</body>
    </html>
  )
}
/* globals.css */
body {
  font-family: var(--font-sans), sans-serif;
}

code {
  font-family: var(--font-mono), monospace;
}

Common Fonts

vinext provides named exports for popular Google Fonts:
import {
  Inter,
  Roboto,
  Roboto_Mono,
  Open_Sans,
  Lato,
  Poppins,
  Montserrat,
  Source_Code_Pro,
  Noto_Sans,
  Raleway,
  Ubuntu,
  Nunito,
  Playfair_Display,
  Merriweather,
  PT_Sans,
  Fira_Code,
  JetBrains_Mono,
  Geist,
  Geist_Mono,
} from 'next/font/google'
For other fonts, use the dynamic accessor:
import googleFonts from 'next/font/google'

const dmSans = googleFonts.DM_Sans({ subsets: ['latin'] })

Limitations

Module-level only: Font loaders must be called at module level (not inside components).
// ✅ Correct
const inter = Inter({ subsets: ['latin'] })

export default function Page() {
  return <div className={inter.className}>Text</div>
}

// ❌ Wrong
export default function Page() {
  const inter = Inter({ subsets: ['latin'] })
  return <div className={inter.className}>Text</div>
}
Local font paths: Must be relative to the file where localFont is called.
Build-time download: Google Fonts are fetched at build time. Network issues during build will cause failures.

Source

View Google Fonts source → View local fonts source → Implementation:
  • /home/daytona/workspace/source/packages/vinext/src/shims/font-google.ts
  • /home/daytona/workspace/source/packages/vinext/src/shims/font-local.ts