[TIL] Next.js google font 사용하기(Tailwind CSS)

대빵·2023년 12월 21일
2

next.js googel font를 Tailwind CSS로 적용 방법을 정리해보기로 했어요.

사용이유

  • next/font는 모든 글꼴 파일에 자동적으로 자체 호스팅이 내장
  • 레이아웃 쉬프트 없이 폰트 사용 가능
  • 구글 폰트에 요청을 보내지 않아도 됨

사용방법

    // 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하기

    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 변수 방식으로 스타일을 지정할 경우에 사용합니다.
    });

subsets? “korean”없다?!

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속성에 할당해야 오류가 해결되요.

subsets, preload

글꼴에 대해 지정된 하위 집합이 누락

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"]
});

className에 전달하고, CSS variable & tailwind와 함께 사용

className을 합치는 함수

export const cls = (...classnames: string[]) => {
  return classnames.join(" ");
};

컴포넌트에 기본으로 사용할 노토산스 className과, CSS variable로 사용할 roboto를 className으로 넘기기

<main className={cls(notoSansKr.className, roboto.variable)}>
  <DefaultLayout>
    <Component {...pageProps} />
  </DefaultLayout>
</main>

tailwind.config에서 theme extend에 fontfamily를 설정

/** @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")],
};

tailwind 클래스를 통해 CSS 변수를 사용

export default function MainComponent() {
  return (
    <div>
      노토산스 글씨입니다.
      <p className="font-roboto">123 $&@ roboto ROBOTO 로보토입니다.</p>
    </div>
  );
}

0개의 댓글