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