129 lines
3.8 KiB
Markdown
129 lines
3.8 KiB
Markdown
|
|
---
|
|||
|
|
title: Шрифты
|
|||
|
|
description: Как подключать шрифты через Next.js Font в проекте.
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Шрифты
|
|||
|
|
|
|||
|
|
Как подключать шрифты через 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 только импортирует готовый шрифт.
|