Ghost

struxadotcloud/struxa

public
Fork0
CodeIssues0Pull requests0
1branch
struxa.claudeskillsnext-best-practicesfont.md
initial commitd4cb9e15 months ago246 lines · 5.1 KB
1# Font Optimization
2
3Use `next/font` for automatic font optimization with zero layout shift.
4
5## Google Fonts
6
7```tsx
8// app/layout.tsx
9import { Inter }
10
11const inter = Inter
12
13export default function RootLayout
14 return (
15 <html lang="
16 <body>{children}
17 </html>
18 );
19}
20```
21
22## Multiple Fonts
23
24```tsx
25import { Inter, Roboto_Mono
26
27const inter = Inter
28 subsets: ["latin"],
29 variable: "--font-inter",
30});
31
32const robotoMono = Roboto_Mono
33 subsets: ["latin"],
34 variable: "--font-roboto-mono",
35});
36
37export default function RootLayout
38 return (
39 <html lang="
40 <body>{children}
41 </html>
42 );
43}
44```
45
46Use in CSS:
47
48```css
49body {
50 font-family: var(--font-inter
51}
52
53code {
54 font-family: var(--font-roboto-mono
55}
56```
57
58## Font Weights and Styles
59
60```tsx
61// Single weight
62const inter = Inter
63 subsets: ["latin"],
64 weight: "400",
65});
66
67// Multiple weights
68const inter = Inter
69 subsets: ["latin"],
70 weight: ["400",
71});
72
73// Variable font (recommended) - includes all weights
74const inter = Inter
75 subsets: ["latin"],
76 // No weight needed - variable fonts support all weights
77});
78
79// With italic
80const inter = Inter
81 subsets: ["latin"],
82 style: ["normal",
83});
84```
85
86## Local Fonts
87
88```tsx
89import localFont from "next/font/local
90
91const myFont = localFont
92 src: "./fonts/MyFont.woff2",
93});
94
95// Multiple files for different weights
96const myFont = localFont
97 src: [
98 {
99 path: "./fonts/MyFont-Regular.woff2",
100 weight: "400",
101 style: "normal",
102 },
103 {
104 path: "./fonts/MyFont-Bold.woff2",
105 weight: "700",
106 style: "normal",
107 },
108 ],
109});
110
111// Variable font
112const myFont = localFont
113 src: "./fonts/MyFont-Variable.woff2",
114 variable: "--font-my-font",
115});
116```
117
118## Tailwind CSS Integration
119
120```tsx
121// app/layout.tsx
122import { Inter }
123
124const inter = Inter
125 subsets: ["latin"],
126 variable: "--font-inter",
127});
128
129export default function RootLayout
130 return (
131 <html lang="
132 <body>{children}
133 </html>
134 );
135}
136```
137
138```js
139// tailwind.config.js
140module.exports = {
141 theme: {
142 extend: {
143 fontFamily: {
144 sans: ["var(--font-inter)"],
145 },
146 },
147 },
148};
149```
150
151## Preloading Subsets
152
153Only load needed character subsets:
154
155```tsx
156// Latin only (most common)
157const inter = Inter
158
159// Multiple subsets
160const inter = Inter
161```
162
163## Display Strategy
164
165Control font loading behavior:
166
167```tsx
168const inter = Inter
169 subsets: ["latin"],
170 display: "swap", //
171});
172
173// Options:
174// 'auto' - browser decides
175// 'block' - short block period, then swap
176// 'swap' - immediate fallback, swap when ready (recommended)
177// 'fallback' - short block, short swap, then fallback
178// 'optional' - short block, no swap (use if font is optional)
179```
180
181## Don't Use Manual Font Links
182
183Always use `next/font` instead of `<link>` tags for Google Fonts.
184
185```tsx
186// Bad: Manual link tag (blocks rendering, no optimization)
187<link href="https://fonts.googleapis.com/css2?family=Inter
188
189// Bad: Missing display and preconnect
190<link href="https://fonts.googleapis.com/css2?family=Inter
191
192// Good: Use next/font (self-hosted, zero layout shift)
193import { Inter }
194
195const inter = Inter
196```
197
198## Common Mistakes
199
200```tsx
201// Bad: Importing font in every component
202// components/Button.tsx
203import { Inter }
204const inter = Inter
205
206// Good: Import once in layout, use CSS variable
207// app/layout.tsx
208const inter = Inter
209
210// Bad: Using @import in CSS (blocks rendering)
211/* globals.css */
212@import url('https://fonts.googleapis.com/css2?family=Inter
213
214// Good: Use next/font (self-hosted, no network request)
215import { Inter }
216
217// Bad: Loading all weights when only using a few
218const inter = Inter
219
220// Good: Specify only needed weights (for non-variable fonts)
221const inter = Inter
222
223// Bad: Missing subset - loads all characters
224const inter = Inter
225
226// Good: Always specify subset
227const inter = Inter
228```
229
230## Font in Specific Components
231
232```tsx
233// For component-specific fonts, export from a shared file
234// lib/fonts.ts
235import { Inter, Playfair_Display
236
237export const inter =
238export const playfair =
239
240// components/Heading.tsx
241import { playfair }
242
243export function Heading({
244 return <h1 className
245}
246```
from
"
next/font/google
"
;
(
{
subsets
:
[
"
latin
"
]
}
)
;
(
{
children
}
:
{
children
:
React
.
ReactNode
}
)
{
en
"
className
=
{
inter
.
className
}
>
</
body
>
}
from
"
next/font/google
"
;
(
{
(
{
(
{
children
}
:
{
children
:
React
.
ReactNode
}
)
{
en
"
className
=
{
`
${
inter
.
variable
}
${
robotoMono
.
variable
}
`
}
>
</
body
>
)
;
)
;
(
{
(
{
"
500
"
,
"
700
"
]
,
(
{
(
{
"
italic
"
]
,
"
;
(
{
(
{
(
{
from
"
next/font/google
"
;
(
{
(
{
children
}
)
{
en
"
className
=
{
inter
.
variable
}
>
</
body
>
(
{
subsets
:
[
"
latin
"
]
}
)
;
(
{
subsets
:
[
"
latin
"
,
"
latin-ext
"
,
"
cyrillic
"
]
}
)
;
(
{
Default - shows fallback, swaps when loaded
"
rel
=
"
stylesheet
"
/>
"
rel
=
"
stylesheet
"
/>
from
'
next/font/google
'
(
{
subsets
:
[
'
latin
'
]
}
)
from
'
next/font/google
'
(
{
subsets
:
[
'
latin
'
]
}
)
//
Creates new instance each time!
(
{
subsets
:
[
'
latin
'
]
,
variable
:
'
--font-inter
'
}
)
'
)
;
from
'
next/font/google
'
(
{
subsets
:
[
'
latin
'
]
}
)
//
Loads all weights
(
{
subsets
:
[
'
latin
'
]
,
weight
:
[
'
400
'
,
'
700
'
]
}
)
(
{}
)
(
{
subsets
:
[
'
latin
'
]
}
)
}
from
"
next/font/google
"
;
Inter
(
{
subsets
:
[
"
latin
"
]
,
variable
:
"
--font-inter
"
}
)
;
Playfair_Display
(
{
subsets
:
[
"
latin
"
]
,
variable
:
"
--font-playfair
"
}
)
;
from
"
@/lib/fonts
"
;
children
}
)
{
=
{
playfair
.
className
}
>
{
children
}
</
h1
>
;