🔠

Next.jsのフォント最適化機能とTailwindCSSでGoogleFontsをめちゃ簡単&安全&スピーディに使う方法

2023/03/12に公開

Next.js13のフォント最適化機能はどういうもの?

Next.js13の新しいフォント最適化機能を使えばフォント(カスタムフォントを含む)を自動的に最適化し、外部ネットワーク要求を削除します。
つまり、フォントまわりのプライバシー保護とパフォーマンス向上が見込める、とのことです。
また、すべてのGoogleFontsに対して利用することができ、フォントのデータはビルド時に静的アセットに変換されるので製品が読み込まれる際に、GoogleFontsを読み込むためのリクエストを無くすことができます。

やりたいこと

  • Next.js(ver13)でGoogleFontを使いたい
    • ※ベータ版のAppRouter構造で試してみる
  • TailwindCSSのクラス名でフォントを適用させたい
    • 一部の要素でフォントを切り替えるのが容易かつ、オートコンプリートやディレクティブが使える

参考資料

https://beta.nextjs.org/docs/optimizing/fonts

手順

では実装の手順を解説していきます。
今回はSource Code Proというソースコードの表示に適したフォントを例にしてみたいと思います。
https://fonts.google.com/specimen/Source+Code+Pro?query=source+code

1. 使いたいフォントをGoogleFontsからimportする

app/layout.tsx
+ // フォント名が複数単語の場合は区切りにアンダースコアを入れる
+ import { Source_Code_Pro } from 'next/font/google';

pages構造ならpages/_app.tsxですね

2. フォントの設定を決める

app/layout.tsx
import { Source_Code_Pro } from 'next/font/google';

+ const source_code_pro = Source_Code_Pro({
+   // 後ほどTailwindCSSで指定する変数名を指定する
+   variable: '--font-source-code-pro',
+   // 利用したいweightやstyleなど指定する
+   weights: [400, 700],
+   style: 'normal',
+   // サブセット
+   subsets: ['latin'],
+   // 代替フォントを表示する
+   display: 'swap',
+ })

フォントで使いたいfont-stylefont-weightなどがある場合は、ここで忘れずに設定しておきましょう。
他のフォント関連オプションの詳細は知りたい方は、以下の公式ドキュメント(英語)を参考にどうぞ。
https://beta.nextjs.org/docs/api-reference/components/font

3. TailwindCSSにフォント設定を追加

tailwind.confi.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./app/**/*.{js,ts,jsx,tsx}', './ui/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {
+     fontFamily: {
+       // font-**で呼び出すclass名 : フォント指定の配列
+       "source-code-pro": ['Source Code Pro', 'monospace'],
+     },
    },
  },
};

4. 要素にclassName属性とクラス名を適用

<code className="font-source-code-pro">Hello World</code>;

これで完了です👌

https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss

その他

フォントのサブセット化をグローバルで設定

以下のように設定ファイルに記述することで、フォントのサブセット化をNext.js全体で有効にすることができます。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true, // Recommended for the `pages` directory, default in `app`.
  experimental: {
    // Required:
    appDir: true,
+   fontLoaders: [
+     { loader: 'next/font/google', options: { subsets: ['latin'] } },
+   ],
  },
};

module.exports = nextConfig;

Discussion