[Front-end] 개발자 공부

Next.js에서 국문/영문 폰트 전역으로 설정하기 (+ next/font 사용)

MOLLY_ 2025. 1. 2. 07:00
728x90

< 목차 >

0. 폰트 파일 다운로드 선택 기준

1. 폰트 파일 추가

2. 로컬 폰트 설정

3. Tailwind CSS 설정

4. RootLayout 의 body 태그에 폰트 주입

5. globals.css 에서 한글 폰트를 font-family 에 주입해 프로젝트 전역에 자동 적용

6. 영어는 className 에 font-sans 를 넣어서 사용

OTHER | 1. ttf, woff 차이

OTHER | 2. 폰트 파일에 이미 굵기가 지정돼있는데 weight: '400' 처럼 또 따로 지정해 줘야 하는 이유

 

 

Next.js에서 폰트 전역으로 설정하는 방법

이번 프로젝트에서는 영어 텍스트에만 자동으로 Montserrat 폰트를 적용하고, 한글 텍스트는 Pretendard 폰트를 적용하는 것으로 디자인 시스템이 나왔다.

 

폰트를 불러오는 방법은 2가지가 있다.

1. 폰트를 매번 폰트 서버(URL)에 요청해서 불러오기

2. 로컬에 폰트 파일을 저장해서 불러오기

 

 

로컬에서 불러오는 게 로딩 속도가 더 빠르기 때문에 이 방법을 채택해서 폰트를 전역에서 사용할 수 있게 해보려 한다. 폰트 공식 사이트에 들어가서 폰트를 다운로드하면 위 사진처럼 많은 파일이 들어가 있다.

 

모든 파일을 반드시 저장해서 사용할 필요는 없다. 프로젝트에서 실제로 사용하는 스타일만 로컬에 저장하고 적용하면 된다.

 

 

0. 폰트 파일 다운로드 선택 기준

1) 프로젝트에서 필요한 폰트 굵기

: 프로젝트에서 사용하는 굵기(예: Regular, Bold, Light 등)만 선택

예를 들어, Regular(400)와 Bold(700)만 사용한다면 해당 파일들만 로컬에 저장

 

2) Italic 스타일 사용 여부

: Italic 스타일(기울임꼴)을 사용할 계획이 없다면 Italic 관련 폰트 파일은 제외해도 됨

 

 

1. 폰트 파일 추가

 

Pretendard 폰트를 다운로드한 뒤, app 하위에 fonts 폴더를 만들어서 넣어준다.

app 하위에 fonts 폴더를 만들어야 하는 게 중요하다. public 폴더에 넣거나 하면 에러가 뜨기 때문이다.

 

 

Montserrat는 구글 폰트이기 때문에 Next.js 에서 제공하는 next/font/google 을 사용하면 브라우저에서 Google에 요청을 보내지 않고도 쉽게 구현할 수 있다.

 

next/font 에는 모든 글꼴 파일에 대한 자동 자체 호스팅 기능이 내장되어 있다고 한다.

기본 CSS 크기 조정 속성 덕분에 레이아웃 이동 없이 웹 글꼴을 최적으로 로드할 수 있다. 이를 사용하면 성능과 개인정보 보호를 염두에 두고 모든 Google 글꼴을 편리하게 사용할 수 있다. CSS 및 글꼴 파일은 빌드 시 다운로드되며 나머지 정적 assets과 함께 자체적으로 호스팅된다고 한다.

 

즉, 자동으로 성능 보장까지 해주기 때문에 안 쓸 이유가 없다.

 

 

2. 로컬 폰트 설정

Pretendard는 따로 로컬에 저장한 거기 때문에 next/font/local 을 사용하여 로컬 폰트로 설정해줘야 한다. PretendardRegular와 함께 사용할 수 있도록 기존의 RootLayout에 추가해도 되지만 나는 폰트를 따로 관리하는 게 나을 것 같아서 fonts 폴더의 index.ts 파일을 만들어서 설정했다.

 

import { Montserrat } from 'next/font/google';
import localFont from 'next/font/local';

export const pretendard = localFont({
  src: [
    { path: './Pretendard-Regular.woff', weight: '400', style: 'normal' },
    { path: './Pretendard-Medium.woff', weight: '500', style: 'normal' },
    {
      path: './Pretendard-SemiBold.woff',
      weight: '600',
      style: 'normal',
    },
  ],
});

export const montserrat = Montserrat({
  subsets: ['latin'],
  variable: '--font-montserrat',
});

 

어떻게 하느냐고? 공식 문서에 다 나와있다.

 

[출처] Next.js - Local Fonts (https://nextjs.org/docs/pages/building-your-application/optimizing/fonts#local-fonts)

 

 

3. Tailwind CSS 설정

Tailwind CSS에서 폰트를 적용하려면 tailwind.config.ts 파일에 다음과 같이 extend 옵션을 설정해야 한다.

 

하이라이트 처리한 부분만 보면 됨

 

영어에 적용할 폰트인 Montserrat만 variable 을 통해 CSS 클래스로 지정한 이유는 Next.js 에서 영문, 국문에 따라 자동으로 적용되게 하는 방법이 없기 때문이다. 공식 문서를 다 뒤져도 찾을 수 없었다.

 

따라서

1. 특정 태그(e.g. <h1>)에 적용하거나

2. className 에 CSS 클래스로 적용하는 것

외에는 2가지 이상의 폰트를 함께 사용할 수 있는 방법이 없었다.

 

나는 그래서 한국어에 적용할 폰트는 전역으로 적용하고, 영어는 Montserrat를 CSS 클래스를 통해 적용하는 방식을 택했다.

 

공식 문서에서는 폰트를 2개 이상 사용할 때는 한국어/영어 모두 자동 처리가 아닌 수동 처리를 해줘야 하는 방법만 나와있길래 이런저런 시도를 하다가 방법을 알아냈다.

 

 

4. RootLayout 의 body 태그에 폰트 주입

 

<body className={${pretendard} ${montserrat.variable}}>

 

한국어에 적용할 폰트는 pretendard 로, 영어에 적용할 폰트는 montserrat.variable 로 주입해 주면 된다.

 

 

5. globals.css 에서 한글 폰트를 font-family 에 주입해 프로젝트 전역에 자동 적용

 

이게 가장 핵심이다.

globals.css 의 font-family 에 ‘pretendard’ 를 넣어줘야 자동으로 프로젝트 전역에 적용된다.

 

 

6. 영어는 className 에 font-sans 를 넣어서 사용

 

자동으로 적용이 안 되니 Tailwind CSS 로 적용하는 수밖에 없다.

 

영어를 지금은 위 사진 속 p 태그 한 군데에서만 사용한다.

하지만 앞으로 프로젝트 규모가 커져서 영어 사용 횟수가 늘어난다고 상상해 보면 영어가 들어가는 곳마다 className 에 font-sans 를 수동으로 일일이 달아줘야 하는 게 너무 멋없다.

 

알아서 자동으로 처리되게 하고 싶은데 아직 그 방법은 못찾았다 🥲😔

 

 

OTHER | 1. ttf, woff 차이

 

폰트를 로컬에 저장하려고 다운로드를 하다 보면 위 사진처럼 폰트 파일 형식의 종류가 다양할 때가 있다. 각각 어떤 장단점을 가지는지 알아보자.

 

일단 ttf와 woff는 폰트 파일 형식의 종류로, 각각의 차이점과 웹에서의 사용 방법은 다음과 같다.

 

 

1) TTF (TrueType Font)

Apple과 Microsoft가 1980년대에 개발한 폰트 형식으로, 오래된 형식이지만 여전히 많은 운영체제와 소프트웨어에서 지원하고 있다.

 

- 폰트의 품질과 디테일이 높음

- 파일 크기가 비교적 큼 (웹에서 로딩 속도에 영향을 미칠 수 있음)

- 웹 사용 가능 여부

   - 브라우저에서 지원되지만, 웹 환경에 최적화되어 있지 않음

   - 모든 브라우저에서 완벽하게 호환되지 않음 (특히 오래된 버전의 IE)

 

 

2) WOFF (Web Open Font Format)

W3C에서 웹 폰트용으로 개발된 형식으로, TTF나 OTF 기반의 데이터를 압축하여 파일 크기를 줄인다.

 

폰트의 메타데이터를 포함하여 웹에서 효율적으로 로드 가능하다.

 

2-1) 장점

- 파일 크기가 작아 로딩 속도가 빠름

- 브라우저 간의 호환성이 뛰어남 (거의 모든 최신 브라우저에서 지원)

- 웹에서 표준으로 사용됨

 

2-2) 웹 사용 가능 여부

- 웹에 최적화되어 있으며 권장됨

- 대부분의 브라우저에서 지원

 

 

3) WOFF2

: 업그레이드된 WOFF 형식이다.

 

- WOFF의 개선된 버전으로 더 높은 압축률 제공

- 파일 크기가 더 작아져 로딩 속도가 더 빠름

- 최신 브라우저에서 지원

 

 

4) 그렇다면 웹에서 무엇을 사용해야 할까?

웹에서는 WOFF 또는 WOFF2를 사용하는 것이 권장된다.

 

이유는 다음과 같다.

- 파일 크기가 작아 로딩 속도가 빠름

- 웹 표준으로, 대부분의 최신 브라우저에서 지원

- 브라우저 간 호환성이 뛰어남

 

그래서 프로젝트에서 사용하는 폰트가 WOFF, WOFF2 를 제공한다면 가급적 WOFF, WOFF2 를 사용하는 게 좋다.

 

나는 WOFF 를 사용했다.

WOFF2 는 WOFF 보다 더 높은 압축률과 로딩 속도가 빠르다는 장점이 있지만 최신 브라우저에서만 제공되기 때문에 대부분의 브라우저에서 지원되는 WOFF 를 채택했다. 그리고 WOFF 만으로도 충분히 로딩 속도가 빠를 것을 기대한다.

 

 

OTHER | 2. 폰트 파일에 이미 굵기가 지정돼있는데 weight: '400' 처럼 또 따로 지정해 줘야 하는 이유

폰트 파일은 일반적으로 파일 자체에 굵기(weight) 정보가 내장되어 있다.

 

그러나 next/font/local 이나 CSS에서 폰트를 로드할 때 명시적으로 weight 를 지정하는 이유브라우저에게 이 폰트가 어떤 굵기 범위에 속하는지 명확히 알려주기 위해서다.

 

굵기를 명시하지 않아도 단일 굵기 사용 시에는 큰 문제가 없을 수 있지만, 다양한 굵기를 사용하는 프로젝트에서는 weight를 명시적으로 지정하는 것이 안전하고 권장된다. 이를 통해 브라우저가 폰트를 정확하게 로드하도록 보장할 수 있다.

 

 

왜 weight를 명시적으로 지정해야 할까?

(1) 폰트 매칭 최적화

: 브라우저는 font-weight 값에 따라 가장 가까운 폰트를 선택함

만약 여러 굵기의 폰트를 사용하는 경우, 명시적으로 weight를 지정하지 않으면 브라우저가 기본적으로 400(Regular)로 간주하거나 잘못된 굵기를 적용할 수 있음

 

(2) 다양한 굵기 지원

: 예를 들어 Pretendard는 다양한 굵기(Thin, Light, Regular, SemiBold 등)를 제공하므로, 각 굵기를 구분하여 사용할 때 weight를 지정해야 브라우저가 정확히 폰트를 로드할 수 있음

 

(3) woff 파일의 메타데이터 의존성

: woff 파일 자체에 굵기 정보가 내장되어 있더라도, 브라우저가 이를 항상 올바르게 해석하지 못할 수 있음. 따라서 weight를 지정해 주는 것이 안전함

 

 

굵기 지정 없이도 동작할 수 있나?

: 굵기 정보를 명시하지 않더라도 다음과 같은 경우에는 동작할 수 있다.

 

- 프로젝트에서 단일 굵기만 사용하는 경우 (Pretendard-Regular.woff 등)

- 모든 텍스트가 동일한 font-weight로 설정된 경우

 

그러나 여러 굵기를 사용하는 경우, 굵기를 명시하지 않으면 올바르게 적용되지 않을 가능성이 있다.

 

 

권장 방식

굵기를 명시적으로 지정하여 폰트를 설정하는 것이 가장 안전하다.

특히 Pretendard처럼 굵기가 세분화된 폰트를 사용할 때는 굵기별로 지정하는 것이 권장된다.

 

const Pretendard = localFont({
  src: [
    { path: './fonts/Pretendard-Regular.woff', weight: '400', style: 'normal' },
    { path: './fonts/Pretendard-Medium.woff', weight: '500', style: 'normal' },
    { path: './fonts/Pretendard-SemiBold.woff', weight: '600', style: 'normal' },
    { path: './fonts/Pretendard-Bold.woff', weight: '700', style: 'normal' },
  ],
  variable: '--font-pretendard',
});

 

 

728x90