Next.js 13×Tailwind @next/fontでGoogleFontsやローカルフォントを高速化してみる
Next.js 13備忘録のこれまで
これまでの記事をご参考ください
今後、執筆予定の記事は下記となります。
気になる方は、いいね!押してもらえると、頑張って早めに書いていきますので、どうぞよろしくお願いします🙇♂️
- Server Component使った実装とは 〜Static RenderingとDynamic Rendering〜
- microCMSを使った検索機能を実装する際に迷ったServer ComponentとClient Componentの使い分け
- App Router を使った際の多言語サイトの作り方
- Next.js 13でハマったPDF読み込みの実装方法
- microCMSのみで実現する、APIキーを隠蔽しつつ、簡易的いいね機能の実装してみる
環境について
Node.js v19.4.0
Next.js 13.4.9
tailwindcss: 3.3.2
@next/font~って何?
公式
また、こちらの記事が素晴らしいです!
上記によると、
FontsをセルフホスティングしてNext側で最適化しており、next/font導入後は、GoogleFontsのリクエストはゼロになっております。
また、ローカルフォントのリクエストは発生していますが、リードタイムも若干低くなる傾向にあるみたいですね。(記事では50msぐらい)
Adobe Fontとか使えるの?
残念ながら、@next/fontはまだ Typekit をサポートしていないみたいです。
ただ、Next.jsでTypekitフォントを使用できます。
Next.js 13 より前には、自動フォント最適化と呼ばれる機能があり、現在も存在しており、Typekitをサポートしています。
どんな感じで書くの?
defalutで書かれてますね。
import './globals.css'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
)
}
variable fontがパフォーマンス面では良いですが、そうでない場合は、下記のようにwidthを指定して書けばよさそうです。
import './globals.css'
import { Noto_Sans_JP } from 'next/font/google'
const notojp = Noto_Sans_JP({
weight: ["400", "500"],
subsets: ["latin"],
display: "swap",
});
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={notojp.className}>{children}</body>
</html>
)
}
Tailwindで個別に当てたい時は?
CSS Variables使えばいけそうです。
import './globals.css'
import { Raleway, Merriweather_Sans } from "@next/font/google";
const raleway = Raleway({
variable: "--display-font",
});
const merriweather = Merriweather_Sans({
variable: "--body-font",
});
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={`${raleway.variable} ${merriweather.variable}`}>{children}</body>
</html>
)
}
これらの変数をtailwindの設定に使って、フォントファミリーを定義することができます。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
fontFamily: {
"display": "var(--display-font)",
"body": "var(--body-font)",
},
extend: {
backgroundImage: {
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
'gradient-conic':
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
},
},
},
plugins: [],
}
複数フォント(ローカルフォント含)を使いつつ、グローバルに当てたい時は?
フォント定義ファイルの使用すると、いい感じ管理しつつ、CSS Variables使えばいけそうです。
例えば、アプリディレクトリのルートにあるstylesフォルダにfonts.tsファイルを作成します。
import { Noto_Sans_JP } from 'next/font/google'
import localFont from 'next/font/local'
const notojp = Noto_Sans_JP({
weight: ["400", "500"],
subsets: ["latin"],
variable: "--font-notojp",
display: "swap",
});
// カスタムローカルフォントを定義する
const ttnorms = localFont({
src: './fonts/TTNorms-Regular.otf',
variable: "--font-ttnorms",
display: 'swap',
})
export { montserrat, notojp, ttnorms }
上記のファイルをインポートします。
import './globals.css'
import { notojp, ttnorms } from '../styles/fonts'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={`${notojp.variable} ${ttnorms.variable}`}>{children}</body>
</html>
)
}
最後に、globals.cssファイルでfont-familyを指定してあげます。
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
font-family: var(--font-ttnorms), var(--font-notojp), sans-serif;
}
まとめ・振り返り
フォント読み込みが早くなるのは嬉しいですよね。
フォント選びは奥が深く、デザイナーさん基本選んでくれることが多いですが、いろんなブラウザや重さなどを考慮すると、フロントエンドの立場から話せるといいですね。
参考
とは言っても、フォントにこだわりがあるのは基本ですし、僕自身フォントの沼にハマってから、看板やアニメのタイトルもフォント意識するようになり、面白いので暇があるとき探ってみるも良さそうです〜
次回は
- Server Component使った実装とは 〜Static RenderingとDynamic Rendering〜
この辺りについて、執筆予定です。
参考
Components: Font | Next.js
Next13新機能、@next/fontでフォント読み込みを高速化してみた
Next.js 13 - next/font の使い方 | TIPS | chocolat
Discussion