Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply Next.js best practices for RSC boundaries, async APIs, routing, metadata, and optimization.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
font.md
1# Font Optimization23Use `next/font` for automatic font optimization with zero layout shift.45## Google Fonts67```tsx8// app/layout.tsx9import { Inter } from 'next/font/google'1011const inter = Inter({ subsets: ['latin'] })1213export default function RootLayout({ children }: { children: React.ReactNode }) {14return (15<html lang="en" className={inter.className}>16<body>{children}</body>17</html>18)19}20```2122## Multiple Fonts2324```tsx25import { Inter, Roboto_Mono } from 'next/font/google'2627const inter = Inter({28subsets: ['latin'],29variable: '--font-inter',30})3132const robotoMono = Roboto_Mono({33subsets: ['latin'],34variable: '--font-roboto-mono',35})3637export default function RootLayout({ children }: { children: React.ReactNode }) {38return (39<html lang="en" className={`${inter.variable} ${robotoMono.variable}`}>40<body>{children}</body>41</html>42)43}44```4546Use in CSS:47```css48body {49font-family: var(--font-inter);50}5152code {53font-family: var(--font-roboto-mono);54}55```5657## Font Weights and Styles5859```tsx60// Single weight61const inter = Inter({62subsets: ['latin'],63weight: '400',64})6566// Multiple weights67const inter = Inter({68subsets: ['latin'],69weight: ['400', '500', '700'],70})7172// Variable font (recommended) - includes all weights73const inter = Inter({74subsets: ['latin'],75// No weight needed - variable fonts support all weights76})7778// With italic79const inter = Inter({80subsets: ['latin'],81style: ['normal', 'italic'],82})83```8485## Local Fonts8687```tsx88import localFont from 'next/font/local'8990const myFont = localFont({91src: './fonts/MyFont.woff2',92})9394// Multiple files for different weights95const myFont = localFont({96src: [97{98path: './fonts/MyFont-Regular.woff2',99weight: '400',100style: 'normal',101},102{103path: './fonts/MyFont-Bold.woff2',104weight: '700',105style: 'normal',106},107],108})109110// Variable font111const myFont = localFont({112src: './fonts/MyFont-Variable.woff2',113variable: '--font-my-font',114})115```116117## Tailwind CSS Integration118119```tsx120// app/layout.tsx121import { Inter } from 'next/font/google'122123const inter = Inter({124subsets: ['latin'],125variable: '--font-inter',126})127128export default function RootLayout({ children }) {129return (130<html lang="en" className={inter.variable}>131<body>{children}</body>132</html>133)134}135```136137```js138// tailwind.config.js139module.exports = {140theme: {141extend: {142fontFamily: {143sans: ['var(--font-inter)'],144},145},146},147}148```149150## Preloading Subsets151152Only load needed character subsets:153154```tsx155// Latin only (most common)156const inter = Inter({ subsets: ['latin'] })157158// Multiple subsets159const inter = Inter({ subsets: ['latin', 'latin-ext', 'cyrillic'] })160```161162## Display Strategy163164Control font loading behavior:165166```tsx167const inter = Inter({168subsets: ['latin'],169display: 'swap', // Default - shows fallback, swaps when loaded170})171172// Options:173// 'auto' - browser decides174// 'block' - short block period, then swap175// 'swap' - immediate fallback, swap when ready (recommended)176// 'fallback' - short block, short swap, then fallback177// 'optional' - short block, no swap (use if font is optional)178```179180## Don't Use Manual Font Links181182Always use `next/font` instead of `<link>` tags for Google Fonts.183184```tsx185// Bad: Manual link tag (blocks rendering, no optimization)186<link href="https://fonts.googleapis.com/css2?family=Inter" rel="stylesheet" />187188// Bad: Missing display and preconnect189<link href="https://fonts.googleapis.com/css2?family=Inter" rel="stylesheet" />190191// Good: Use next/font (self-hosted, zero layout shift)192import { Inter } from 'next/font/google'193194const inter = Inter({ subsets: ['latin'] })195```196197## Common Mistakes198199```tsx200// Bad: Importing font in every component201// components/Button.tsx202import { Inter } from 'next/font/google'203const inter = Inter({ subsets: ['latin'] }) // Creates new instance each time!204205// Good: Import once in layout, use CSS variable206// app/layout.tsx207const inter = Inter({ subsets: ['latin'], variable: '--font-inter' })208209// Bad: Using @import in CSS (blocks rendering)210/* globals.css */211@import url('https://fonts.googleapis.com/css2?family=Inter');212213// Good: Use next/font (self-hosted, no network request)214import { Inter } from 'next/font/google'215216// Bad: Loading all weights when only using a few217const inter = Inter({ subsets: ['latin'] }) // Loads all weights218219// Good: Specify only needed weights (for non-variable fonts)220const inter = Inter({ subsets: ['latin'], weight: ['400', '700'] })221222// Bad: Missing subset - loads all characters223const inter = Inter({})224225// Good: Always specify subset226const inter = Inter({ subsets: ['latin'] })227```228229## Font in Specific Components230231```tsx232// For component-specific fonts, export from a shared file233// lib/fonts.ts234import { Inter, Playfair_Display } from 'next/font/google'235236export const inter = Inter({ subsets: ['latin'], variable: '--font-inter' })237export const playfair = Playfair_Display({ subsets: ['latin'], variable: '--font-playfair' })238239// components/Heading.tsx240import { playfair } from '@/lib/fonts'241242export function Heading({ children }) {243return <h1 className={playfair.className}>{children}</h1>244}245```246