next.js googel font를 Tailwind CSS로 적용 방법을 정리해보기로 했어요.
// pages/_app.js
import { Inter } from 'next/font/google' // 해당 폰트의 함수를 사용합니다.
const inter = Inter({ subsets: ['latin'] }) // 변수를 선언하고, 함수의 인자로 스타일을 지정합니다.
export default function MyApp({ Component, pageProps }) {
return (
<main className={inter.className}> {/* className을 통해 하위 컴포넌트에서 폰트를 사용합니다. */}
<Component {...pageProps} />
</main>
)
}
import { Roboto, Noto_Sans_KR } from "next/font/google"; // Roboto와 한글 NotoSans를 사용합니다.
const notoSansKr = Noto_Sans_KR({
// preload: true, 기본값
subsets: ["latin"], // 또는 preload: false
weight: ["100", "400", "700", "900"], // 가변 폰트가 아닌 경우, 사용할 fontWeight 배열
});
const roboto = Roboto({
subsets: ["latin"], // preload에 사용할 subsets입니다.
weight: ["100", "400", "700"],
variable: "--roboto", // CSS 변수 방식으로 스타일을 지정할 경우에 사용합니다.
});
Noto_Sans_KR를 불러와서 작성하다 보니 subsets: []
안에 작성할 값에 korean은 없어요.
한국어를 쓰고 싶은데 subsets에는 latin, greek, vietnamese 밖에 없으면서, subsets
인수를 삭제하면 에러가 생겨요.
이 오류의 경우 TypeScript에서 발생하는걸로 subsets
속성에 잘못된 값이 할당되어있음을 나타내는데요 Google Font에서 지원하는 서브셋 중 하나여야 되요.
cyrillic: 키릴 문자체계를 사용하는 언어(예: 러시아어, 우크라이나어, 불가리아어 등)
latin: 라틴 문자체계를 사용하는 언어(예: 영어, 프랑스어, 스페인어 등)
latin-ext: 라틴 확장 문자체계를 사용하는 언어(특수 기호 및 다양한 언어의 확장된 문자)
vietnamese: 베트남어를 위한 문자체계
cyrillic-ext: 키릴 문자체계의 확장을 지원하는 언어
greek: 그리스 문자체계를 사용하는 언어
greek-ext: 그리스 문자체계의 확장을 지원하는 언어
중 하나를 선택해 subsets
속성에 할당해야 오류가 해결되요.
next.js의 구글 폰트는 자동으로 폰트를 preload합니다. 이를 위해 지정하는 값이
subset(하위 집합) 입니다. preload를 사용하여 글꼴 파일의 크기가 줄어들고
성능이 향상됩니다. 미리 로드할 하위 집합을 정의해야 합니다.
하위 집합을 지정하지 않으면 preload 경고가 발생합니다.
vercel의 잘 정리된 공식 문서를 참고하자면, subsets은 preload할 하위 집합을 지정해야되요. 글꼴 파일을 줄이고 성능이 향상시켜요. 그리고 preload의 기본값은 true이기 때문에, subsets가 없으면 preload할 대상을 알 수 없으므로 경고가 발생해요.
그런데 아쉽지만 subsets에서 한글은 제공하지 않아요..ㅎㅎ
공식문서 하단의 Noto_Sans_JP 예시와 같이, preload를 false로 지정해도 되요. 하지만 영문에도 노토산스 폰트를 사용할 계획이 있다면 preload를 안할 이유가 있을까요? 반대로 presets에 존재하지 않는, 예를 들어 영어가 아닌 다국어에만 해당 폰트를 사용하는 경우라면 preload를 false로 사용할 수 있어요.
const notoSansJp = Noto_Sans_JP({
// preload: true, 기본값
preload: false,
weight: ["100", "400", "700"]
});
export const cls = (...classnames: string[]) => {
return classnames.join(" ");
};
<main className={cls(notoSansKr.className, roboto.variable)}>
<DefaultLayout>
<Component {...pageProps} />
</DefaultLayout>
</main>
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {
fontFamily: { // 폰트패밀리
roboto: ["var(--roboto)"], // 다음과 같이 배열 안에 string으로 작성합니다.
},
},
},
variants: {
extend: {},
},
plugins: [require("tailwind-scrollbar-hide")],
};
export default function MainComponent() {
return (
<div>
노토산스 글씨입니다.
<p className="font-roboto">123 $&@ roboto ROBOTO 로보토입니다.</p>
</div>
);
}