概要
Next.js v13 がリリースされました。
主な変更点の1つが @next/font
の追加。@next/font
には以下のような特徴があります。
- Automatically optimizes your fonts, including custom fonts(カスタムフォントを含めたフォントの最適化)
- Removes external network requests for improved privacy and performance(フォント読込のための外部リクエストをしない)
- Built-in automatic self-hosting for any font file(フォントファイルをセルフホストしてくれる)
- Zero layout shift automatically using the CSS size-adjust property(CSS size-adjust を利用してレイアウトシフトをゼロに)
ただしまだベータ版機能のようですが。
利用方法は全て以下のページに書かれているのですが、自分でも利用してみたので記録を書いていきます。
セットアップ
パッケージを新規インストール。
npm install @next/font
Google フォントの場合は @next/font/google
が利用可能です。今回は Oswald フォントが利用したかったので、以下の1文を追加。
import { Oswald } from '@next/font/google'
次に、設定事項を記載。
const oswald = Oswald({ variable: '--font-oswald', subsets: ['latin'], })
CSS custom properties を利用しており、font-family: var('--font-oswald');
のようにフォントを適用したいため、 variable
を設定しました。ここで CSS custom properties の名称を設定できます。
さらに、subsets
も指定。デフォルトでは preload
が true となっており、その場合は subsets
指定が必須です。指定が無いと以下のような警告が出ます。
warn - The @next/font/google font Oswald has no selected subsets. Please specify subsets in the function call or in your next.config.js, otherwise no fonts will be preloaded. Read more: https://nextjs.org/docs/messages/google-fonts-missing-subsets
Oswald フォントには、キリル文字・ラテン文字・ベトナム文字のサブセットがあるようでしたが、ラテン文字のみ必要だったので、 subsets: ['latin']
を指定しました。
すべての設定項目はこちらに。
ちなみに、型定義がしっかりしており、Oswald の場合は以下のような感じ。何が指定可能なのか、分かりやすい。
export declare function Oswald(options?: { weight?: '200' | '300' | '400' | '500' | '600' | '700' | 'variable' | Array<'200' | '300' | '400' | '500' | '600' | '700'>; style?: 'normal' | Array<'normal'>; display?: Display; variable?: CssVariable; preload?: boolean; fallback?: string[]; adjustFontFallback?: boolean; subsets?: Array<'cyrillic' | 'cyrillic-ext' | 'latin' | 'latin-ext' | 'vietnamese'>; }): FontModule;
そして、設定済みのフォントを適用。サイト全体に適用したいので、 app.tsx
で適用しました。
function MyApp({ Component, pageProps }: AppProps) { return ( <main className={oswald.variable}> <Component {...pageProps} /> </main> ) }
これで、サイト全体で font-family: var('--font-oswald');
が指定可能となりました。(1枚噛ませる DOM が増えるのはちょっと微妙な気がしますが…
挙動を確認してみると、確かに外部(https://fonts.gstatic.com)へのリクエストがなくなり、セルフホストしたフォントを読み込んでいる。フォント読込&適用に伴うレイアウトシフトもしっかり無くなっていました。
Vercel 上でもフォントファイルがデプロイされていることを確認できました。
その他、自前のフォントを使う方法、CSS custom properties ではない方法については、公式ページをご覧ください。