Next.jsJuniorTechnical

Что такое модуль next/font и почему его рекомендуют использовать?

next/font загружает шрифты при билде и отдаёт их с того же домена, автоматически добавляя preload, size-adjust для минимизации CLS и устраняя запросы к внешним CDN вроде Google Fonts.

Модуль next/font

Модуль next/font встраивает шрифты напрямую в процесс сборки. Он загружает файлы шрифтов во время билда, размещает их в /_next/static/media/ и генерирует CSS-переменную, которую вы применяете через className. Никакого запроса на fonts.googleapis.com в браузере не происходит.

Два источника: Google Fonts и локальные файлы

// app/layout.tsx — Google Font
import { Inter, Roboto_Mono } from "next/font/google";

const inter = Inter({
  subsets: ["latin", "cyrillic"],
  variable: "--font-inter",
  display: "swap",
});

const robotoMono = Roboto_Mono({
  subsets: ["latin"],
  variable: "--font-mono",
  weight: ["400", "700"],
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={`${inter.variable} ${robotoMono.variable}`}>
      <body className="font-sans">{children}</body>
    </html>
  );
}
// Локальный шрифт
import localFont from "next/font/local";

const myFont = localFont({
  src: [
    { path: "../fonts/MyFont-Regular.woff2", weight: "400" },
    { path: "../fonts/MyFont-Bold.woff2", weight: "700" },
  ],
  variable: "--font-custom",
  display: "swap",
});

Подключение через Tailwind

// tailwind.config.ts
import type { Config } from "tailwindcss";

export default {
  theme: {
    extend: {
      fontFamily: {
        sans: ["var(--font-inter)"],
        mono: ["var(--font-mono)"],
      },
    },
  },
} satisfies Config;

Почему рекомендуют использовать

  • Нет внешних запросов — шрифты отдаются с того же домена, что устраняет DNS-lookup и TLS-handshake к Google.
  • Автоматический size-adjust — Next.js вычисляет size-adjust для fallback-шрифта, чтобы минимизировать layout shift (CLS).
  • font-display: swap — задаётся явно, текст виден сразу с системным шрифтом.
  • Приватность — IP пользователя не передаётся Google.
  • Preload — Next.js автоматически добавляет <link rel="preload"> для нужных начертаний.
  • Subset-контроль — загружается только нужный subset (latin, cyrillic), а не весь файл шрифта.

Подводные камни

  • Экземпляр шрифта нужно создавать за пределами компонента (на уровне модуля) — иначе он пересоздаётся при каждом рендере и файл шрифта будет дублироваться в бандле.
  • Если указать variable, нужно применять className к <html> или <body>, иначе CSS-переменная не будет доступна дочерним компонентам.
  • Google Fonts требует интернет-доступа во время next build — в CI без доступа к сети сборка упадёт. Для таких сред используйте next/font/local.
  • Опция weight обязательна для шрифтов с несколькими начертаниями (кроме variable fonts) — без неё Next.js загрузит все доступные веса.
  • Параметр display: "optional" полностью предотвращает layout shift, но шрифт может не показаться при медленной сети — аккуратно с выбором стратегии.
  • В Turbopack режиме некоторые edge-случаи с localFont и относительными путями могут давать ошибки — всегда проверяйте путь относительно файла, где объявляется шрифт.
  • Кириллические шрифты из Google нужно явно запросить через subsets: ["cyrillic"] — иначе символы будут рендериться fallback-шрифтом.

Common mistakes

  • Подключать @font-face в CSS параллельно с next/font
  • Грузить все начертания вместо нужного подмножества
  • Импортировать загрузчик внутри функции компонента
  • Забыть указать кириллический subset для русского текста

What the interviewer is testing

  • Знает, что шрифты самохостятся
  • Понимает роль display: swap и size-adjust
  • Умеет использовать variable с Tailwind/CSS-vars
  • Выбирает нужные subsets и weight

Sources

Related topics