Post

Next.js (13. Font Optimization) 정리

Next.js (13. Font Optimization) 정리

0. 폰트 최적화


next/font 모듈은 폰트를 자동으로 최적화하고 외부 네트워크 요청을 제거한다. 모든 폰트 파일을 빌드 타임에 자체 호스팅해 레이아웃 시프트(CLS) 없이 웹 폰트를 제공한다.

사용 방법은 다음과 같다.

  1. next/font/google 또는 next/font/local에서 폰트를 import한다.
  2. 옵션을 전달해 함수로 호출한다.
  3. 적용할 요소의 className에 설정한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// app/layout.tsx

import { Geist } from 'next/font/google'

const geist = Geist({
  subsets: ['latin'],
})

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ko" className={geist.className}>
      <body>{children}</body>
    </html>
  )
}

폰트는 사용된 컴포넌트 범위로 스코핑된다. 앱 전체에 적용하려면 루트 레이아웃에 추가한다.

1. Google 폰트


next/font/google에서 원하는 폰트를 import하면 Google 폰트를 자동으로 자체 호스팅한다. 폰트가 정적 에셋으로 저장되고 배포 도메인에서 직접 제공되므로, 브라우저가 Google에 별도 요청을 보내지 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// app/layout.tsx

import { Geist } from 'next/font/google'

const geist = Geist({
  subsets: ['latin'],
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="ko" className={geist.className}>
      <body>{children}</body>
    </html>
  )
}

1-1. Variable Font vs weight 지정


최적의 성능과 유연성을 위해 가변 폰트(variable font) 사용을 권장한다. 가변 폰트를 사용할 수 없는 경우 weight를 명시해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// app/layout.tsx

import { Roboto } from 'next/font/google'

const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="ko" className={roboto.className}>
      <body>{children}</body>
    </html>
  )
}

2. 로컬 폰트


next/font/local에서 localFont를 import하고 src에 로컬 폰트 파일 경로를 지정한다. 경로는 localFont를 호출한 파일 기준 상대 경로로 해석되며, public 폴더나 app 폴더 안 어디든 저장할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// app/layout.tsx

import localFont from 'next/font/local'

const myFont = localFont({
  src: './my-font.woff2',
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="ko" className={myFont.className}>
      <body>{children}</body>
    </html>
  )
}

2-1. 여러 파일 사용


하나의 폰트 패밀리에 여러 파일을 사용하려면 src를 배열로 전달한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const roboto = localFont({
  src: [
    {
      path: './Roboto-Regular.woff2',
      weight: '400',
      style: 'normal',
    },
    {
      path: './Roboto-Italic.woff2',
      weight: '400',
      style: 'italic',
    },
    {
      path: './Roboto-Bold.woff2',
      weight: '700',
      style: 'normal',
    },
    {
      path: './Roboto-BoldItalic.woff2',
      weight: '700',
      style: 'italic',
    },
  ],
})
This post is licensed under CC BY 4.0 by the author.