メインコンテンツまでスキップ

フォント最適化

next/fontは、フォント(カスタムフォントを含む)を自動的に最適化し、外部ネットワークリクエストを削除してプライバシーとパフォーマンスを向上させます。

🎥 視聴: next/fontの使用方法について詳しく学びましょう → YouTube (6分)

next/fontには、任意の フォントファイルに対する組み込みの自動セルフホスティングが含まれています。これにより、CSSのsize-adjustプロパティを使用して、レイアウトシフトをゼロにしてWebフォントを最適にロードできます。

この新しいフォントシステムでは、パフォーマンスとプライバシーを考慮して、すべてのGoogle Fontsを便利に使用できます。CSSとフォントファイルはビルド時にダウンロードされ、他の静的アセットと一緒にセルフホスティングされます。ブラウザからGoogleへのリクエストは送信されません。

Google Fonts

任意のGoogle Fontを自動的にセルフホスティングします。フォントはデプロイメントに含まれ、デプロイメントと同じドメインから提供されます。ブラウザからGoogleへのリクエストは送信されません。

使用したいフォントをnext/font/googleから関数としてインポートすることで始めましょう。最良のパフォーマンスと柔軟性を得るために、可変フォントを使用することをお勧めします。

app/layout.tsx
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>
)
}

可変フォントを使用できない場合は、太さを指定する必要があります

app/layout.tsx
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>
)
}

配列を使用して複数の太さやスタイルを指定できます:

app/layout.js
const roboto = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
display: 'swap',
})

Good to know: 複数の単語を持つフォント名にはアンダースコア(_)を使用してください。例:Roboto MonoRoboto_Monoとしてインポートする必要があります。

サブセットの指定

Google Fontsは自動的にサブセット化されます。これにより、フォントファイルのサイズが削減され、パフォーマンスが向上します。これらのサブセットのどれをプリロードするかを定義する必要があります。preloadtrueのときにサブセットを指定しないと警告が表示されます。

これは、関数呼び出しに追加することで行えます:

app/layout.tsx
const inter = Inter({ subsets: ['latin'] })

Font APIリファレンスを参照して、詳細情報を確認してください。

複数のフォントを使用する

アプリケーションで複数のフォントをインポートして使用できます。2つのアプローチがあります。

最初のアプローチは、フォントをエクスポートし、インポートして必要な場所でそのclassNameを適用するユーティリティ関数を作成することです。これにより、フォントはレンダリングされたときにのみプリロードされます:

app/fonts.ts
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',
})
app/layout.tsx
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>
)
}
app/page.tsx
import { roboto_mono } from './fonts'

export default function Page() {
return (
<>
<h1 className={roboto_mono.className}>My page</h1>
</>
)
}

上記の例では、Interはグローバルに適用され、Roboto Monoは必要に応じてインポートして適用できます。

または、CSS変数を作成し、お好みのCSSソリューションで使用することもできます:

app/layout.tsx
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>
)
}
app/global.css
html {
font-family: var(--font-inter);
}

h1 {
font-family: var(--font-roboto-mono);
}

上記の例では、Interはグローバルに適用され、任意の<h1>タグはRoboto Monoでスタイルされます。

推奨事項: 各新しいフォントはクライアントがダウンロードする追加のリソースであるため、複数のフォントは控えめに使用してください。

ローカルフォント

next/font/localをインポートし、ローカルフォントファイルのsrcを指定します。最良のパフォーマンスと柔軟性を得るために、可変フォントを使用することをお勧めします。

app/layout.tsx
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>
)
}

単一のフォントファミリーに複数のファイルを使用したい場合、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またはローカルフォントから任意のフォントを使用できます)。フォントをvariableオプションでロードしてCSS変数名を定義し、それをinterに割り当てます。次に、inter.variableを使用してCSS変数をHTMLドキュメントに追加します。

app/layout.tsx
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>
)
}

最後に、Tailwind CSSの設定にCSS変数を追加します:

tailwind.config.js
/** @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-sansfont-monoユーティリティクラスを使用して、要素にフォントを適用できます。

プリロード

サイトのページでフォント関数が呼び出されると、そのフォントはグローバルに利用可能であり、すべてのルートでプリロードされるわけではありません。むしろ、使用されるファイルの種類に基づいて関連するルートでのみプリロードされます:

  • ユニークページの場合、そのページのユニークルートでプリロードされます
  • レイアウトの場合、レイアウトでラップされたすべてのルートでプリロードされます
  • root レイアウトの場合、すべてのルートでプリロードされます

フォントの再利用

localFontまたはGoogleフォント関数を呼び出すたびに、そのフォントはアプリケーション内で1つのインスタンスとしてホストされます。したがって、同じフォント関数を複数のファイルでロードすると、同じフォントの複数のインスタンスがホストされます。この状況では、次のことをお勧めします:

  • フォントローダー関数を1つの共有ファイルで呼び出す
  • 定数としてエクスポートする
  • このフォントを使用したい各ファイルで定数をインポートする