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

Font最適化

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

🎥 Watch: next/fontの使い方をもっと知る →YouTube(6 分).

next/fontには、あらゆるフォントファイルに対する自動セルフホスティング機能が組み込まれています。これは、使用されている CSS のsize-adjust属性のおかげで、レイアウトシフトをゼロにしてウェブフォントを最適に読み込むことができることを意味します。

この新しいフォントシステムにより、パフォーマンスとプライバシーを考慮したすべての 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',
})
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 Monotが適用されます。

推奨:新しいフォントが追加されるたびに、クライアントがダウンロードしなければならないリソースが増えるため、複数のフォントの使用は控えめにしましょう。

ローカルのフォント

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

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>
)
}

1 つのフォント・ファミリーに対して複数のファイルを使いたい場合は、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/googleInterフォントを使用しています(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>
)
}

最後に、CSS 変数をTailwind 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-sansユーティリティクラスとfont-monoユーティリティクラスを使って、要素にフォントを適用できるようになりました。

プリロード

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

  • 固有のページであれば、そのページの固有のルートにプリロードされます
  • レイアウトの場合、レイアウトによってラップされたすべてのルートにプリロードされます
  • ルートレイアウトの場合、すべてのルートにプリロードされます

フォントの再利用

localFont または Google フォント関数を呼び出すたびに、そのフォントはアプリケーション内で 1 つのインスタンスとしてホストされます。したがって、同じフォント関数を複数のファイルで読み込むと、同じフォントの複数のインスタンスがホストされることになります。このような場合は、次のようにすることをお勧めします:

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

API リファレンス

next/font API についてもっと知りたい場合は以下を参照してください。

/docs/app-router/api-reference/components/font