Skip to content

[global] next/font/google을 로컬 폰트로 바꿔 빌드 실패 차단 - #281

Merged
s2yeons merged 4 commits into
developfrom
fix/next-font-local
Nov 2, 2026
Merged

s2yeons merged 4 commits into
developfrom
fix/next-font-local

Conversation

@s2yeons

@s2yeons s2yeons commented Oct 29, 2026

Copy link
Copy Markdown
Member

개요 💡

모든 앱이 next/font/google로 빌드 시점에 Google Fonts에서 폰트를 받는데, Google이 간헐적으로 확장자 없는 폰트 URL을 돌려주면 Next 로더가 null[1]에서 터져 CI 빌드가 코드와 관계없이 실패하였습니다. 업스트림 수정이 아직 릴리스되지 않아, 폰트를 @fontsource 패키지에서 next/font/local로 불러오도록 전환하였습니다. 빌드가 더 이상 Google Fonts에 요청하지 않습니다.

작업내용 ⌨️

  • packages/shared/src/fonts: 6개 앱에 복제되어 있던 DM_Sans, JetBrains_Mono, Press_Start_2P 설정을 공통 모듈로 모으고, <html> className에 넣을 fontVariables를 내보내도록 하였습니다. @repo/shared/fonts로 가져옵니다.
  • 6개 앱 layout.tsx에서 next/font/google을 제거하고 fontVariables를 사용하도록 변경하였습니다. Galmuri는 기존처럼 각 앱에 두었습니다.
  • --font-sans, --font-mono, --font-pixel 변수, 굵기, display: 'swap', font-family 이름('DM Sans' 등)은 그대로 유지하였습니다. globals.css의 .font-pixel, .font-code가 이 이름을 직접 참조합니다.
  • latin-ext 포함: next/font/local은 src 항목마다 unicode-range를 줄 수 없어 subset마다 따로 호출하고 같은 font-family를 지정하였습니다. Google Fonts처럼 latin만 preload하고, latin-ext는 해당 문자가 쓰일 때만 받습니다.
  • DM Sans, JetBrains Mono는 이슈에서 제안한 정적 굵기 파일 대신 @fontsource-variable/*의 가변 폰트를 사용하였습니다. 기존 빌드에서도 Google이 가변 폰트 한 파일을 주고 있었고, 정적 파일을 쓰면 preload가 3개(약 90KB)에서 8개(약 134KB)로 늘어나기 때문입니다. 굵기는 기존 범위(400 700, 400 600)로 제한하였습니다. 패키지는 모두 OFL-1.1입니다.

검증

  • 6개 앱 빌드, 타입 검사, 테스트, lint가 통과하였습니다.
  • 전환 전후 client 빌드 CSS를 비교하여 font-family 이름, CSS 변수, latin/latin-ext unicode-range, preload 파일 수(Galmuri 포함 4개)가 같은 것을 확인하였습니다.

관련 이슈 🚨

리뷰 요청사항 👀

  • 로딩 중 대체 폰트(Arial) 보정 값이 폰트 파일에서 계산되도록 바뀌어 1~2% 달라졌습니다(예: DM Sans size-adjust 104.53% → 105.13%). 폰트를 받은 뒤의 화면은 같지만, 로딩 중 레이아웃 흔들림이 없는지 확인 부탁드립니다.
  • 기존에는 JetBrains Mono, Press Start 2P의 cyrillic, greek, vietnamese 파일도 포함되어 있었으나, 이슈 범위에 맞춰 latin, latin-ext만 넣었습니다. 해당 문자는 대체 폰트로 보입니다.
  • latin-ext 호출은 @font-face만 만들면 되지만 next/font가 const 할당을 요구하여, 쓰지 않는 변수에 eslint-disable-next-line을 달았습니다.

@vercel

vercel Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
datagsm-front-admin Ready Ready Preview Oct 29, 2026 11:32pm UTC
datagsm-front-client Ready Ready Preview Oct 29, 2026 11:32pm UTC
datagsm-front-docs Ready Ready Preview Oct 29, 2026 11:32pm UTC
datagsm-front-oauth Ready Ready Preview Oct 29, 2026 11:32pm UTC
datagsm-front-projects Ready Ready Preview Oct 29, 2026 11:32pm UTC
datagsm-front-status Ready Ready Preview Oct 29, 2026 11:32pm UTC

Request Review

@pr-agent-demo pr-agent-demo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Summary

This PR replaces next/font/google across all apps with locally bundled fonts loaded through next/font/local and @fontsource, to prevent CI build failures caused by intermittent Google Fonts responses.

It introduces a shared font configuration module at packages/shared/src/fonts, exports a common fontVariables string, and updates six app layouts to stop importing fonts directly from next/font/google.

The change also preserves the existing CSS font variables (--font-sans, --font-mono, --font-pixel), font-family names, display strategy, and preload behavior as closely as possible, while moving DM Sans and JetBrains Mono to variable fonts from @fontsource-variable.


What Changed

  • Removed next/font/google font setup from all app layouts

    • Affected apps:
      • admin
      • client
      • docs
      • oauth
      • projects
      • status
    • Previously, each app independently configured:
      • DM_Sans
      • JetBrains_Mono
      • Press_Start_2P
    • These repeated definitions were removed.
  • Introduced a shared font module

    • New file: packages/shared/src/fonts/index.ts
    • Exported via @repo/shared/fonts
    • Provides a single fontVariables value used by all apps.
  • Fonts are now loaded locally

    • Uses:
      • @fontsource-variable/dm-sans
      • @fontsource-variable/jetbrains-mono
      • @fontsource/press-start-2p
    • These are loaded through next/font/local instead of fetching Google Fonts at build time.
  • Added package dependencies

    • Updated packages/shared/package.json
    • Updated pnpm-lock.yaml
  • Kept Galmuri app-local

    • Galmuri11 remains defined directly in app layouts where used, because it was already local.

Main Motivation

The PR fixes a CI instability issue: next/font/google depended on Google Fonts during build, and intermittent malformed or failing font URLs caused builds to fail even when the application code itself was unchanged.

By switching to local @fontsource assets, the build no longer depends on Google Fonts availability.

This closes issue #277.


Notable Implementation Details

  • Latin and latin-ext subsets are separated

    • Each font is split into:
      • latin
      • latin-ext
    • This mimics the previous Google Fonts behavior more closely.
  • unicode-range is declared manually

    • Because next/font/local does not support per-src unicode-range directly, each subset is registered as a separate font entry with matching font-family and explicit unicode-range.
  • Preload behavior is preserved

    • latin fonts are preloaded.
    • latin-ext fonts are registered but not preloaded.
  • Variable fonts are used for DM Sans and JetBrains Mono

    • This avoids increasing preload file count.
    • Weight ranges are constrained to match previous usage:
      • DM Sans: 400 700
      • JetBrains Mono: 400 600
  • CSS variable names remain unchanged

    • --font-sans
    • --font-mono
    • --font-pixel
    • This keeps existing Tailwind/global CSS references working.

Verification Mentioned in the PR

The author states that:

  • Builds for all 6 apps pass
  • Type checks pass
  • Tests pass
  • Lint passes
  • Before/after generated CSS was compared for:
    • font-family names
    • CSS variables
    • latin / latin-ext unicode ranges
    • preload file count

Potential Review Areas

This is a global styling / build-infrastructure change, so the main review risks are around visual consistency and font loading behavior:

  • Font fallback metrics may differ slightly

    • The PR notes that adjustFontFallback values changed by about 1–2%, which could affect layout during font loading.
  • Subset coverage is narrower than before

    • Cyrillic, Greek, and Vietnamese subsets were intentionally not included.
    • Those characters would now fall back to system fonts.
  • Unused variables with lint disables

    • Some latin-ext font constants exist only to generate @font-face declarations, requiring eslint-disable-next-line @typescript-eslint/no-unused-vars.
  • Dependency footprint increases

    • Three new font packages are added to the shared package.

Overall

This PR is a reliability-focused refactor that removes a flaky external build dependency, centralizes font configuration, and preserves the existing font architecture as closely as possible. The primary risk is not functional behavior, but subtle rendering differences during font loading or for characters outside the retained latin/latin-ext subsets.


3 inline comment(s)

Comment thread packages/shared/src/fonts/index.ts Resolved
Comment thread packages/shared/src/fonts/index.ts Resolved
Comment thread packages/shared/src/fonts/index.ts Resolved
@s2yeons
s2yeons merged commit a2a31ec into develop Nov 2, 2026
8 checks passed

This branch was successfully deployed

5 active deployments
Preview – datagsm-front-docs — 7aaf36cf Deployed Oct 29, 2026 by vercel[bot]
Preview – datagsm-front-oauth — 7aaf36cf Deployed Oct 29, 2026 by vercel[bot]
Preview – datagsm-front-admin — 7aaf36cf Deployed Oct 29, 2026 by vercel[bot]
Preview – datagsm-front-status — 7aaf36cf Deployed Oct 29, 2026 by vercel[bot]
Preview – datagsm-front-client — 7aaf36cf Deployed Oct 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants