next/font

ネクストフォント

Web フォントを最適化しよう

Next.js には Web フォントを最適化して利用できるようにする機能が用意されています。Google Fonts や Adobe Fonts に対応しています。@next/font は、Next.js 用のフォント管理ライブラリです。@next/font を使用すると、フォントファイルをプロジェクトにインポートし、CSS で使用できる CSS 変数を生成できます。これにより、フォントファイルを管理しやすく、パフォーマンスを向上させることができます。

Next.js 13.4

まずは、tsconfig.json の paths に @/fonts": ["./styles/fonts"] を追加します。

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "paths": {
      "@/*": ["./src/*"],
      "@/fonts": ["./styles/fonts"] // 追加
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

app/page.tsx に Google Fonts の Lato を導入します。@next/font/google からインポートし、変数に代入します。フォント名にスペースがあるときはアンダーバーを入れます。

src/app/page.tsx

import { Lato } from 'next/font/google'

const Lato700 = Lato({
  weight: '700',
  preload: false,
  //subsets: ['latin'],
})

export default function Home() {
  return (
    <>
      <main>
        <p>ここはFontが反映されません。</p>
        <h1 className={Lato700.className}>ここはFontが反映されます。</h1>
      </main>
    </>
  )
}

これで反映されます。

パラメーター

キー 説明
src フォントファイルの URL または、フォントファイルへのパス。複数のフォントファイルを指定する場合は、配列で指定します。
weight フォントウェイト。指定しない場合は、デフォルトのウェイトが使用されます。
style フォントスタイル。指定しない場合は、デフォルトのスタイルが使用されます。
subsets フォントサブセット。指定しない場合は、すべてのサブセットが使用されます。
axes フォント軸。指定しない場合は、すべての軸が使用されます。
display フォント表示。指定しない場合は、デフォルトの表示が使用されます。
preload フォントファイルのプリロード。true を指定すると、ブラウザがフォントファイルを事前に読み込みます。
fallback フォントが見つからない場合に使用するフォント。複数のフォントファイルを指定する場合は、配列で指定します。
adjustFontFallback フォントフォールバック調整。true を指定すると、ブラウザがフォントフォールバックアルゴリズムを調整します。
variable フォント変数。指定しない場合は、デフォルトのフォント変数が使用されます。
declarations フォント宣言。指定しない場合は、デフォルトのフォント宣言が使用されます。

subsets のエラーが出る場合

次のようなエラーがでる場合は、フォントに対してプリロードを有効にしていますが、サブセットを指定していないことを示しています。つまり、フォントは特定の言語または地域に対してプリロードされません。

`next/font` error:
Preload is enabled but no subsets were specified for font `Source Sans Pro`. Please specify subsets or disable preloading if your intended subset can't be preloaded.
Available subsets: `cyrillic`, `cyrillic-ext`, `greek`, `greek-ext`, `latin`, `latin-ext`, `vietnamese`

エラーを修正するには、フォントに対して 1 つ以上のサブセットを指定する必要があります。

const Lato700 = Lato({
  weight: '700',
  subsets: ['latin'],
})

例えば、Source Sans Pro フォントのサブセットは次のとおりです。

  • キリル文字
  • キリル文字拡張
  • ギリシャ語
  • ギリシャ語拡張
  • ラテン語
  • ラテン語拡張
  • ベトナム語

サブセットを指定するには、フォントオブジェクトを作成するときに subsets プロパティを使用できます。

const Lato700 = Lato({
  weight: '700',
  subsets: ['latin'],
})

特定の言語または地域に対してフォントをプリロードする必要がない場合は、preload プロパティを false に設定してプリロードを無効にできます。

const Lato700 = Lato({
  weight: '700',
  preload: false,
  //subsets: ['latin'],
})

マルチプルフォント

複数のフォントをインポートして使用できます。フォントをエクスポートし、インポートし、必要に応じてそのクラス名を適用するユーティリティ関数を作成することです。これにより、フォントはレンダリングされるときにのみプリロードされます。

import { Rato, Roboto_Mono } from 'next/font/google'

export const inter = Rato({
  subsets: ['latin'],
  display: 'swap',
})

export const roboto_mono = Roboto_Mono({
  subsets: ['latin'],
  display: 'swap',
})

_document.tsx を使うパターン

Next.js で Google Fonts を導入するために、_document.tsx ファイルを作成し、Google Fonts のサイトでコピーした<link> タグをページに追加します。

// pages/_document.tsx
import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

ここで、href の値を先ほど Google Fonts からコピーしたものに置き換えてください。

ビルドすると CSS が最適化されたコードが生成されます。

CSS モジュールを使ったフォント適用

次に、CSS モジュールを使って、Google Fonts で導入したフォントを適用しましょう。ここでは、index.tsx ファイルと、対応する CSS モジュールファイル index.module.css を例に取り上げます。

// pages/index.tsx
import styles from './index.module.css'

const HomePage = () => {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>Hello, Next.js!</h1>
    </div>
  )
}

export default HomePage
/* pages/index.module.css */
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-color: #f0f0f0;
}

.title {
  font-family: 'Roboto', sans-serif;
  font-weight: 500;
  font-size: 48px;
}

ここで、font-family の値に Google Fonts で選択したフォント名(この例では 'Roboto')を指定しています。

グローバルスタイルでフォント適用

別の方法として、_app.tsx ファイルを使ってグローバルスタイルにフォントを適用することもできます。まず、styles/globals.css ファイルを作成し、以下のように記述します。

/* styles/globals.css */
body {
  font-family: 'Roboto', sans-serif;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

次に、_app.tsx ファイルで styles/globals.css をインポートします。

// pages/_app.tsx
import '../styles/globals.css'
import type { AppProps } from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

export default MyApp

これで、Google Fonts で選択したフォントがプロジェクト全体に適用されます。

フォント関数の引数

公式のドキュメントによると、<link> タグの href 属性には、以下のような引数を指定することができます。

キー font/google font/local データ型 必須/オプション
src 文字列またはオブジェクトの配列 必須
weight 文字列または配列 必須/オプション
style 文字列または配列 オプション
subsets 文字列の配列 オプション
axes 文字列の配列 オプション
display 文字列 オプション
preload 真偽値 オプション
fallback 文字列の配列 オプション
adjustFontFallback 真偽値または文字列 オプション
variable 文字列 オプション
declarations オブジェクトの配列 オプション

next/font | Next.js