フォント最適化
next/font
は、フォント(カスタムフォントを含む)を自動的に最適化し、外部ネットワークへのリクエストを削除することでプライバシーとパフォーマンスの向上を図ります。
🎥 視聴:
next/font
の使用方法について学びましょう → YouTube (6分)。
next/font
には、任意の フォントファイル用のビルトインの自己ホスティング機能が含まれています。これにより、CSSの size-adjust
プロパティを活用し、レイアウトシフトのない形でウェブフォントを最適に読み込むことができます。
この新しいフォントシステムを使用すると、すべてのGoogleフォントをパフォーマンスとプライバシーを考慮して簡単に使用できるようになります。CSSとフォントファイルはビルド時にダウンロードされ、その他の静的アセットとともに自己ホスティングされます。ブラウザからGoogleへのリクエストは送信されません。
Googleフォント
任意のGoogleフォントを自動で自己ホスティングできます。フォントはデプロイに含まれ、デプロイと同じドメインから提供されます。ブラウザからGoogleへのリクエストは送信されません。
使用したいフォントを next/font/google
から関数としてインポートすることで、始められます。最良のパフォーマンスと柔軟性のために、可変フォント の使用をお勧めします。
- TypeScript
- JavaScript
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>
)
}
可変フォントを使用できない場合、重さを指定する必要があります:
- TypeScript
- JavaScript
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',
})
Good to know: 複数の単語からなるフォント名にはアンダースコア(_)を使用しましょう。例:
Roboto Mono
はRoboto_Mono
としてインポートする必要があります。
サブセットの指定
Googleフォントは自動でサブセット化されます。これにより、フォントファイルのサイズが削減され、パフォーマンスが向上します。これらのサブセットのうち、どれをプリロードするかを定義する必要があります。 preload
が true
のときにサブセットを指定しないと、警告が表示されます。
以下のように関数呼び出しに追加して行うことができます:
- TypeScript
- JavaScript
const inter = Inter({ subsets: ['latin'] })
const inter = Inter({ subsets: ['latin'] })
Font API リファレンスを参照して詳細を確認してください。
複数フォントの使用
アプリケーション内で複数のフォントをインポートして使用できます。以下の2つの方法があります。
最初の方法はフォントをエクスポートし、インポートし、必要な場所で className
を適用するユーティリティ関数を作成することです。これにより、フォントはレンダリングされたときにのみプリロードされます:
- TypeScript
- JavaScript
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',
})
- TypeScript
- JavaScript
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>
)
}
- TypeScript
- JavaScript
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変数を作成できます:
- TypeScript
- JavaScript
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
を指定します。最良のパフォーマンスと柔軟性のために、可変フォントの使用をお勧めします。
- TypeScript
- JavaScript
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',
},
],
})
Font API リファレンスを参照して詳細を確認してください。
Tailwind CSSの使用
next/font
はCSS変数を介して Tailwind CSS で使用できます。
以下の例では、next/font/google
のフォント Inter
を使用しています(Googleフォントやローカルフォントから任意のフォントを使用できます)。CSS変数の名前を定義するために variable
オプションを使用し、inter
に割り当てます。そして、inter.variable
を使用してHTMLドキュメントにCSS変数を追加します。
- TypeScript
- JavaScript
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>
)
}
最後に、Tailwind CSSの設定に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
ユーティリティクラスを使用してフォントを要素に適用できます。
プリロード
サイトのページでフォント関数が呼び出されると、グローバルに利用可能になり、すべてのルートでプリロードされるわけではありません。フォントは、それが使用されるファイルのタイプに基づいて関連するルートでのみプリロードされます:
- ユニークなページの場合、そのページのユニークなルートでのみプリロードされます
- レイアウトの場合、レイアウトにラップされたすべてのルートでプリロードされます
- root レイアウトの場合、すべてのルートでプリロードされます
フォントの再利用
localFont
または Googleフォント関数が呼び出されるたびに、そのフォントはアプリケーション内で1つのインスタンスとしてホスティングされます。したがって、同じフォント関数を複数のファイルで読み込むと、同じフォントの複数のインスタンスがホスティングされます。このような状況では、次のことを行うことをお勧めします:
- 共有ファイル内でフォントローダー関数を呼び出す
- それを定数としてエクスポートする
- このフォントを使用したい各ファイルでその定数をインポートする