Skip to content

Шрифты

Как подключать шрифты через Next.js Font в проекте.

Назначение

Шрифты подключаются через next/font. Это стандартный способ Next.js: шрифты загружаются без ручных <link>, @font-face и настройки preconnect.

Шрифт подключается в точке инициализации приложения, а в CSS используется через переменную.

Google Fonts

tsx
// src/app/layout.tsx
import type { ReactNode } from 'react'
import { Inter } from 'next/font/google'
import 'shared/styles/global.css'

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

type RootLayoutProps = {
  children: ReactNode
}

export default function RootLayout({ children }: RootLayoutProps) {
  return (
    <html lang="ru" className={inter.variable}>
      <body>{children}</body>
    </html>
  )
}
css
/* src/shared/styles/global.css */
body {
  font-family: var(--font-main), system-ui, sans-serif;
}

Локальные шрифты

Каждый локальный шрифт размещается в отдельной папке внутри src/shared/fonts/. В этой же папке лежит .font.ts, где объявляется localFont.

text
src/shared/fonts/
└── roboto/
    ├── roboto.font.ts
    ├── Roboto-Regular.woff2
    ├── Roboto-Italic.woff2
    ├── Roboto-Bold.woff2
    └── Roboto-BoldItalic.woff2
ts
// src/shared/fonts/roboto/roboto.font.ts
import localFont from 'next/font/local'

export 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',
    },
  ],
  variable: '--font-main',
  display: 'swap',
})

app/ импортирует готовый объект шрифта и только подключает его к документу:

tsx
// src/app/layout.tsx
import type { ReactNode } from 'react'
import { roboto } from 'shared/fonts/roboto/roboto.font'
import 'shared/styles/global.css'

type RootLayoutProps = {
  children: ReactNode
}

export default function RootLayout({ children }: RootLayoutProps) {
  return (
    <html lang="ru" className={roboto.variable}>
      <body>{children}</body>
    </html>
  )
}

Путь в localFont указывается относительно .font.ts, поэтому файлы шрифта импортируются коротко: ./Roboto-Regular.woff2.

Если шрифтов несколько, у каждого своя папка и свой .font.ts.

Правила

  • Использовать next/font/google или next/font/local.
  • Не подключать шрифты через ручные <link> и @font-face без необходимости.
  • Подключать шрифты один раз — в корневом layout через готовый объект шрифта.
  • Использовать CSS-переменные variable, а не жёстко прописывать семейство в каждом компоненте.
  • Локальные файлы шрифтов хранить в src/shared/fonts/{font-name}/ рядом с {font-name}.font.ts.
  • Не объявлять localFont внутри src/app/layout.tsx; layout только импортирует готовый шрифт.