Оптимизация шрифтов
next/font
автоматически оптимизирует ваши шрифты (включая пользовательские) и исключает внешние сетевые запросы для улучшения конфиденциальности и производительности.
🎥 Видео: Узнайте больше об использовании
next/font
→ YouTube (6 минут).
next/font
включает встроенную автоматическую самозагрузку для любых файлов шрифтов. Это означает, что вы можете оптимально загружать веб-шрифты без сдвигов макета благодаря использованию свойства CSS size-adjust
.
Эта новая система шрифтов также позволяет удобно использовать все шрифты Google с учётом производительности и конфиденциальности. CSS и файлы шрифтов загружаются во время сборки и размещаются вместе с остальными статическими ресурсами. Браузер не отправляет запросы к Google.
Шрифты Google
Автоматическая самозагрузка любых шрифтов Google. Шрифты включаются в развёртывание и обслуживаются с того же домена, что и ваше приложение. Браузер не отправляет запросы к Google.
Начните с импорта нужного шрифта из next/font/google
как функции. Рекомендуем использовать вариативные шрифты для лучшей производительности и гибкости.
import { Inter } from 'next/font/google'
// Для вариативных шрифтов не нужно указывать вес
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
)
}
import { Inter } from 'next/font/google'
// Для вариативных шрифтов не нужно указывать вес
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
)
}
Если вы не можете использовать вариативный шрифт, необходимо указать вес:
import { Roboto } from 'next/font/google'
const roboto = Roboto({
weight: '400',
subsets: ['latin'],
display: 'swap',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={roboto.className}>
<body>{children}</body>
</html>
)
}
import { Roboto } from 'next/font/google'
const roboto = Roboto({
weight: '400',
subsets: ['latin'],
display: 'swap',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={roboto.className}>
<body>{children}</body>
</html>
)
}
Вы можете указать несколько весов и/или стилей, используя массив:
const roboto = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
display: 'swap',
})
Полезно знать: Используйте подчёркивание (_) для названий шрифтов из нескольких слов. Например,
Roboto Mono
следует импортировать какRoboto_Mono
.
Указание подмножества
Шрифты Google автоматически субсетятся. Это уменьшает размер файла шрифта и повышает производительность. Вам нужно определить, какие подмножества вы хотите предзагрузить. Если не указать подмножества при включённом preload
, будет выдано предупреждение.
Это можно сделать, добавив их в вызов функции:
const inter = Inter({ subsets: ['latin'] })
const inter = Inter({ subsets: ['latin'] })
Подробнее см. в справочнике API шрифтов.
Использование нескольких шрифтов
Вы можете импортировать и использовать несколько шрифтов в вашем приложении. Есть два подхода.
Первый подход — создать служебную функцию, которая экспортирует шрифт, импортирует его и применяет className
там, где нужно. Это гарантирует, что шрифт будет предзагружен только при его отображении:
import { Inter, Roboto_Mono } from 'next/font/google'
export const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export const roboto_mono = Roboto_Mono({
subsets: ['latin'],
display: 'swap',
})
import { Inter, Roboto_Mono } from 'next/font/google'
export const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export const roboto_mono = Roboto_Mono({
subsets: ['latin'],
display: 'swap',
})
import { inter } from './fonts'
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={inter.className}>
<body>
<div>{children}</div>
</body>
</html>
)
}
import { inter } from './fonts'
export default function Layout({ children }) {
return (
<html lang="en" className={inter.className}>
<body>
<div>{children}</div>
</body>
</html>
)
}
import { roboto_mono } from './fonts'
export default function Page() {
return (
<>
<h1 className={roboto_mono.className}>My page</h1>
</>
)
}
import { roboto_mono } from './fonts'
export default function Page() {
return (
<>
<h1 className={roboto_mono.className}>My page</h1>
</>
)
}
В примере выше Inter
будет применён глобально, а Roboto Mono
можно импортировать и применять по необходимости.
Альтернативно, вы можете создать CSS-переменную и использовать её с предпочитаемым CSS-решением:
import { Inter, Roboto_Mono } from 'next/font/google'
import styles from './global.css'
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
display: 'swap',
})
const roboto_mono = Roboto_Mono({
subsets: ['latin'],
variable: '--font-roboto-mono',
display: 'swap',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}>
<body>
<h1>My App</h1>
<div>{children}</div>
</body>
</html>
)
}
import { Inter, Roboto_Mono } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
display: 'swap',
})
const roboto_mono = Roboto_Mono({
subsets: ['latin'],
variable: '--font-roboto-mono',
display: 'swap',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}>
<body>
<h1>My App</h1>
<div>{children}</div>
</body>
</html>
)
}
html {
font-family: var(--font-inter);
}
h1 {
font-family: var(--font-roboto-mono);
}
В примере выше Inter
будет применён глобально, а все теги <h1>
будут стилизованы с Roboto Mono
.
Рекомендация: Используйте несколько шрифтов умеренно, так как каждый новый шрифт — это дополнительный ресурс, который клиент должен загрузить.
Локальные шрифты
Импортируйте next/font/local
и укажите src
вашего локального файла шрифта. Рекомендуем использовать вариативные шрифты для лучшей производительности и гибкости.
import localFont from 'next/font/local'
// Файлы шрифтов могут находиться внутри `app`
const myFont = localFont({
src: './my-font.woff2',
display: 'swap',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={myFont.className}>
<body>{children}</body>
</html>
)
}
import localFont from 'next/font/local'
// Файлы шрифтов могут находиться внутри `app`
const myFont = localFont({
src: './my-font.woff2',
display: 'swap',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={myFont.className}>
<body>{children}</body>
</html>
)
}
Если вы хотите использовать несколько файлов для одного семейства шрифтов, src
может быть массивом:
const roboto = localFont({
src: [
{
path: './Roboto-Regular.woff2',
weight: '400',
style: 'normal',
},
{
path: './Roboto-Italic.woff2',
weight: '400',
style: 'italic',
},
{
path: './Roboto-Bold.woff2',
weight: '700',
style: 'normal',
},
{
path: './Roboto-BoldItalic.woff2',
weight: '700',
style: 'italic',
},
],
})
Подробнее см. в справочнике API шрифтов.
С Tailwind CSS
next/font
можно использовать с Tailwind CSS через CSS-переменные.
В примере ниже мы используем шрифт Inter
из next/font/google
(вы можете использовать любой шрифт Google или локальный). Загрузите ваш шрифт с опцией variable
, чтобы определить имя CSS-переменной, и присвойте его inter
. Затем используйте inter.variable
, чтобы добавить CSS-переменную в ваш HTML-документ.
import { Inter, Roboto_Mono } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
})
const roboto_mono = Roboto_Mono({
subsets: ['latin'],
display: 'swap',
variable: '--font-roboto-mono',
})
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}>
<body>{children}</body>
</html>
)
}
import { Inter, Roboto_Mono } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
})
const roboto_mono = Roboto_Mono({
subsets: ['latin'],
display: 'swap',
variable: '--font-roboto-mono',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}>
<body>{children}</body>
</html>
)
}
Наконец, добавьте CSS-переменную в конфигурацию Tailwind CSS:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
'./app/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {
fontFamily: {
sans: ['var(--font-inter)'],
mono: ['var(--font-roboto-mono)'],
},
},
},
plugins: [],
}
Теперь вы можете использовать классы font-sans
и font-mono
для применения шрифтов к элементам.
Предзагрузка
Когда функция шрифта вызывается на странице вашего сайта, шрифт не становится глобально доступным и предзагруженным на всех маршрутах. Вместо этого он предзагружается только на связанных маршрутах в зависимости от типа файла, в котором он используется:
- Если это уникальная страница, шрифт предзагружается на уникальном маршруте этой страницы.
- Если это макет, шрифт предзагружается на всех маршрутах, обёрнутых этим макетом.
- Если это корневой макет, шрифт предзагружается на всех маршрутах.
Повторное использование шрифтов
Каждый раз, когда вы вызываете функцию localFont
или шрифта Google, этот шрифт размещается как один экземпляр в вашем приложении. Поэтому, если вы загружаете одну и ту же функцию шрифта в нескольких файлах, размещается несколько экземпляров одного шрифта. В этой ситуации рекомендуется сделать следующее:
- Вызовите функцию загрузки шрифта в одном общем файле
- Экспортируйте её как константу
- Импортируйте константу в каждый файл, где вы хотите использовать этот шрифт