コンテンツにスキップ

フォントの最適化

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

🎥 解説: next/font の使用方法について詳しく学ぶ → YouTube (6分)

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

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

Googleフォント

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

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

すべてのページでフォントを使用するには、以下に示すように/pages以下の_app.jsファイルに追加します。

pages/_app.js
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'] })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={inter.className}>
      <Component {...pageProps} />
    </main>
  )
}

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

pages/_app.js
import { Roboto } from 'next/font/google'
 
const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={roboto.className}>
      <Component {...pageProps} />
    </main>
  )
}

配列を使用して複数のウェイトやスタイルを指定できます。

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

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

<head>でフォントを適用

ラッパーやclassNameを使わずに、以下のように<head>内にフォントを挿入して使用することもできます。

pages/_app.js
import { Inter } from 'next/font/google'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <style jsx global>{`
        html {
          font-family: ${inter.style.fontFamily};
        }
      `}</style>
      <Component {...pageProps} />
    </>
  )
}

単一ページでの使用

単一のページでフォントを使用するには、以下に示すようにその特定のページに追加します。

pages/index.js
import { Inter } from 'next/font/google'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function Home() {
  return (
    <div className={inter.className}>
      <p>Hello World</p>
    </div>
  )
}

サブセットの指定

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

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

pages/_app.js
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',
})

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

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

app/global.css
html {
  font-family: var(--font-inter);
}
 
h1 {
  font-family: var(--font-roboto-mono);
}

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

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

ローカルフォント

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

pages/_app.js
import localFont from 'next/font/local'
 
// Font files can be colocated inside of `pages`
const myFont = localFont({ src: './my-font.woff2' })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={myFont.className}>
      <Component {...pageProps} />
    </main>
  )
}

単一のフォントファミリーに複数のファイルを使用したい場合は、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は、CSS変数を介してTailwind CSSと連携して使用できます。

以下の例では、next/font/googleInterフォントを使用しています(Googleまたはローカルフォントの任意のフォントを使用できます)。variableオプションでフォントをロードしてCSS変数名を定義し、それをinterに割り当てます。次に、inter.variableを使用してCSS変数をHTMLドキュメントに追加します。

pages/_app.js
import { Inter } from 'next/font/google'
 
const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={`${inter.variable} font-sans`}>
      <Component {...pageProps} />
    </main>
  )
}

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

プリロード

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

  • もし特定のページで使用される場合、そのページの固有のルートでプリロードされます。
  • もしカスタムAppで使用される場合、サイトの/pages以下のすべてのルートでプリロードされます。

フォントの再利用

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

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