コンテンツへスキップ

フォントの最適化

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

🎥動画:next/font の使用方法の詳細はこちら → YouTube(6分)

next/font には、あらゆるフォントファイルに対する**組み込みの自動セルフホスティング**が含まれています。つまり、基になるCSSのsize-adjustプロパティを使用することで、レイアウトシフトなしでウェブフォントを最適に読み込むことができます。

この新しいフォントシステムでは、パフォーマンスとプライバシーを考慮して、すべてのGoogleフォントを簡単に使用できます。CSSとフォントファイルはビルド時にダウンロードされ、残りの静的アセットと共にセルフホストされます。**ブラウザからGoogleにリクエストが送信されることはありません。**

Google Fonts

Googleフォントを自動的にセルフホストします。フォントはデプロイメントに含まれ、デプロイメントと同じドメインから提供されます。**ブラウザからGoogleにリクエストが送信されることはありません。**

next/font/googleから使用したいフォントを関数としてインポートして開始します。パフォーマンスと柔軟性を最大限に高めるには、可変フォントの使用をお勧めします。

app/layout.tsx
import { Inter } from 'next/font/google'
 
// If loading a variable font, you don't need to specify the font weight
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',
})

知っておくと良い点:複数の単語を含むフォント名にはアンダースコア(_)を使用します。例:Roboto MonoRoboto_Monoとしてインポートする必要があります。

サブセットの指定

Googleフォントは自動的にサブセット化されます。これにより、フォントファイルのサイズが縮小され、パフォーマンスが向上します。preloadtrueの場合、これらのサブセットのうちプリロードするものを定義する必要があります。サブセットを指定せずにpreloadtrueに設定すると、警告が表示されます。

これは、関数呼び出しに追加することで実行できます。

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

詳細については、フォント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'
 
// Font files can be colocated inside of `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',
    },
  ],
})

詳細については、フォントAPIリファレンスを参照してください。

Tailwind CSSを使用する場合

next/fontは、Tailwind CSSCSS変数を通して使用できます。

以下の例では、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ユーティリティクラスを使用して、要素にフォントを適用できるようになりました。

プリロード

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

  • それが独自のページの場合、そのページの一意のルートでプリロードされます。
  • それがレイアウトの場合、レイアウトによってラップされているすべてのルートでプリロードされます。
  • それがルートレイアウトの場合、すべてのルートでプリロードされます。

フォントの再利用

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

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

APIリファレンス

next/font APIの詳細については、こちらをご覧ください。