사용자 정의 글꼴 사용
이 안내서는 프로젝트에 웹 글꼴을 추가하고 컴포넌트에서 사용하는 방법을 설명합니다.
Astro는 통합되고, 완전히 사용자 정의 가능하며, 타입 안정성을 갖춘 API를 통해 파일 시스템 및 다양한 글꼴 제공업체(예: Fontsource, Google)의 글꼴을 사용할 수 있는 방법을 제공합니다.
웹 글꼴은 로드 시간과 렌더링 시간 모두에서 페이지 성능에 영향을 미칠 수 있습니다. 이 API는 프리로드 링크, 최적화된 대체 글꼴, 정해진 기본값 등 자동 웹 글꼴 최적화를 통해 사이트 성능을 유지하는 데 도움을 줍니다. 일반적인 사용 예시를 참조하세요.
폰트 API는 글꼴을 다운로드하고 캐시하여 사이트에서 제공함으로써 성능과 개인 정보 보호에 중점을 둡니다. 이를 통해 사용자 데이터를 서드파티 사이트로 전송하는 것을 방지하고, 모든 방문자에게 일관된 글꼴 세트를 제공할 수 있습니다.
사용자 정의 글꼴 구성
섹션 제목: “사용자 정의 글꼴 구성”Astro 프로젝트에 사용자 정의 글꼴을 등록하는 것은 Astro 구성 파일의 fonts 옵션을 통해 이루어집니다.
사용하려는 각 글꼴에 대해 이름, CSS 변수, 그리고 Astro 글꼴 제공업체를 지정해야 합니다.
Astro는 Adobe, Bunny, Fontshare, Fontsource, Google, Google Icons, NPM과 같은 가장 인기 있는 글꼴 제공업체에 대한 내장 지원과 로컬 글꼴 파일 사용을 지원합니다. 또한 성능과 방문자 경험을 최적화하기 위해 글꼴 구성을 추가로 사용자 정의할 수 있습니다.
로컬 글꼴 파일 사용
섹션 제목: “로컬 글꼴 파일 사용”이 예시는 DistantGalaxy.woff2 글꼴 파일을 사용하여 사용자 정의 글꼴을 추가하는 방법을 보여줍니다.
-
글꼴 파일을
src/디렉터리 안에 추가합니다. 예를 들어src/assets/fonts/와 같이 추가할 수 있습니다. -
Astro 설정 파일에서 로컬 글꼴 제공업체를 사용하여 새 글꼴 패밀리를 만들고 포함할 변형을 지정합니다.
astro.config.mjs import { defineConfig, fontProviders } from "astro/config";export default defineConfig({fonts: [{provider: fontProviders.local(),name: "DistantGalaxy",cssVariable: "--font-distant-galaxy",options: {variants: [{src: ['./src/assets/fonts/DistantGalaxy.woff2'],weight: 'normal',style: 'normal'}]}}]}); -
이제 글꼴이 구성되었으며 프로젝트에서 사용할 수 있도록 페이지 헤드에 추가할 준비가 되었습니다.
Fontsource 사용
섹션 제목: “Fontsource 사용”Astro는 Google Fonts 및 기타 오픈 소스 글꼴 사용을 간소화하는 Fontsource 지원을 포함하여 여러 글꼴 제공업체를 기본으로 지원합니다.
다음 예시에서는 Fontsource를 사용하여 사용자 정의 글꼴 지원을 추가하는 방법을 보여주지만, Astro의 내장 글꼴 제공업체(예: Adobe, Bunny)에서도 과정은 비슷합니다.
-
Fontsource의 카탈로그에서 사용하고 싶은 글꼴을 찾으세요. 이 예시에서는 Roboto를 사용합니다.
-
Astro 설정 파일에서 Fontsource 제공업체를 사용하여 새로운 글꼴 패밀리를 만듭니다.
astro.config.mjs import { defineConfig, fontProviders } from "astro/config";export default defineConfig({fonts: [{provider: fontProviders.fontsource(),name: "Roboto",cssVariable: "--font-roboto",}]}); -
이제 글꼴이 구성되었으며 프로젝트에서 사용할 수 있도록 페이지 헤드에 추가할 준비가 되었습니다.
사용자 정의 글꼴 적용
섹션 제목: “사용자 정의 글꼴 적용”글꼴이 구성된 후에는 식별 CSS 변수와 함께 페이지 헤드에 추가해야 합니다. 그런 다음, 이 변수를 사용하여 페이지 스타일을 정의할 수 있습니다.
-
필요한
cssVariable속성을 가진<Font />컴포넌트를 페이지 헤드에 가져와 포함합니다. 일반적으로 전용Head.astro컴포넌트나 레이아웃 컴포넌트에 직접 포함합니다.src/layouts/Layout.astro ---import { Font } from "astro:assets";---<html><head><Font cssVariable="--font-distant-galaxy" /></head><body><slot /></body></html> -
해당 레이아웃으로 렌더링되는 모든 페이지(레이아웃 컴포넌트 자체 포함)에서 이제 글꼴의
cssVariable로 스타일을 정의하여 사용자 정의 글꼴을 적용할 수 있습니다.다음 예시에서는
<h1>제목에 사용자 정의 글꼴이 적용되지만, 단락<p>에는 적용되지 않습니다.src/pages/example.astro ---import Layout from "../layouts/Layout.astro";---<Layout><h1>In a galaxy far, far away...</h1><p>Custom fonts make my headings much cooler!</p><style>h1 {font-family: var(--font-distant-galaxy);}</style></Layout>
글꼴 프리로드
섹션 제목: “글꼴 프리로드”글꼴 프리로드는 다른 중요한 리소스의 로드를 차단하거나 현재 페이지에 불필요한 글꼴을 다운로드할 수 있으므로 신중하게 사용해야 합니다. 스크롤 없이 바로 보이는 영역의 콘텐츠를 표시하는 데 필요한 가장 핵심적인 글꼴만 프리로드하는 것을 고려하세요.
글꼴을 프리로드하려면 해당 <Font /> 컴포넌트에 preload 속성을 전달하세요. 하나의 글꼴에 여러 파일이 대응하는 경우, 배열을 전달하여 프리로드할 파일을 지정할 수도 있습니다.
---import { Font } from "astro:assets";---
<html> <head> <Font cssVariable="--font-distant-galaxy" preload /> </head> <body> <slot /> </body></html>Tailwind에 글꼴 등록
섹션 제목: “Tailwind에 글꼴 등록”Tailwind를 사용하여 스타일링하는 경우, font-face CSS 속성으로 스타일을 적용하지 않습니다.
대신, 사용자 정의 글꼴을 구성하고 페이지 헤드에 추가한 후에는 Tailwind 구성을 업데이트하여 글꼴을 등록해야 합니다.
@import "tailwindcss";
@theme inline { --font-sans: var(--font-roboto);}/** @type {import("tailwindcss").Config} */export default { content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"], theme: { extend: {}, fontFamily: { sans: ["var(--font-roboto)"] } }, plugins: []};자세한 내용은 사용자 정의 글꼴 모음 추가에 대한 Tailwind 문서를 확인하세요.
가변 글꼴 사용
섹션 제목: “가변 글꼴 사용”프로젝트에서 가변 글꼴을 사용하려면, 제공업체 설정에서 개별 굵기 대신 사용 가능한 굵기 범위를 지정합니다.
로컬 글꼴 파일 사용 시, 글꼴 변형의 weight 속성을 해당 글꼴에 사용 가능한 정확한 굵기 범위에 해당하는 문자열로 설정하여 글꼴이 가변 글꼴임을 지정할 수 있습니다.
다음 예시는 Inter를 사용 가능한 굵기 범위를 가진 로컬 가변 글꼴로 구성하는 방법을 보여줍니다.
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [{ provider: fontProviders.local(), name: "Inter", cssVariable: "--font-inter", options: { variants: [ { weight: "100 900", style: "normal", src: ["./src/assets/fonts/InterVariable.woff2"], }, ], }, }]});다른 제공업체(예: Fontsource)를 사용하여 가변 글꼴을 지원하는 경우, weights 속성을 글꼴에 사용 가능한 정확한 굵기 범위가 포함된 배열로 설정하여 글꼴의 가변 버전을 요청할 수 있습니다.
다음 예시는 Fontsource에서 Fira Code를 사용 가능한 굵기 범위를 가진 가변 글꼴로 다운로드합니다.
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [{ cssVariable: "--font-fira-code", name: "Fira Code", provider: fontProviders.fontsource(), styles: ["normal"], weights: ["300 700"], }]});대체 글꼴 사용자 정의
섹션 제목: “대체 글꼴 사용자 정의”대체 글꼴은 기본 글꼴이 아직 로드되지 않았거나, 누락된 문자를 포함하거나, 어떤 이유로든 로드할 수 없을 때 사용됩니다. 대체 글꼴이 기본 글꼴과 크게 다를 경우 페이지 로딩 중에 레이아웃 이동이 발생할 수 있습니다.
이를 방지하기 위해 Astro는 마지막으로 정의된 대체 글꼴이 일반 글꼴 패밀리인 경우 최적화된 대체 글꼴을 생성하려고 시도합니다. 기본적으로 sans-serif를 사용하지만, 이는 기본 글꼴의 원하는 모양과 일치하지 않을 수 있습니다. 글꼴 구성에서 이를 조정할 수 있습니다.
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [{ provider: fontProviders.fontsource(), name: "Cousine", cssVariable: "--font-cousine", fallbacks: ["monospace"] }]});글꼴 구성에서 font.optimizedFallbacks를 false로 설정하여 기본 최적화를 선택 해제할 수도 있습니다. 그러면 Astro는 추가 자동 처리 없이 구성에 지정된 대체 글꼴을 사용합니다.
프로그래밍 방식으로 글꼴 데이터에 접근
섹션 제목: “프로그래밍 방식으로 글꼴 데이터에 접근”Astro는 fontData 객체를 통해 글꼴 패밀리 데이터에 프로그래밍 방식으로 접근할 수 있는 저수준 API를 제공합니다. 이는 API 라우트에서 Satori를 사용하여 오픈 그래프 이미지를 생성하는 것과 같이 글꼴 파일에 직접 접근해야 하는 고급 사용 사례에 유용할 수 있습니다.
이 저수준 API는 Astro가 프로젝트를 위해 다운로드한 모든 글꼴 파일과 해당 메타데이터에 접근할 수 있도록 해줍니다. 이는 필요한 특정 글꼴 파일을 찾기 위해 글꼴 파일을 필터링하고, 빌드 출력 구조를 기반으로 사용할 파일 경로를 결정하는 것은 사용자 책임이라는 것을 의미합니다.
현재 API에는 빌드 시 출력 경로에서 글꼴 파일을 수동으로 로드해야 하는 알려진 제한이 있습니다.
이 과정을 간소화하기 위한 새로운 API가 개발 중이며 향후 릴리스에서 제공될 예정입니다. GitHub 이슈를 구독하여 진행 상황을 확인할 수 있습니다.
다음 예시는 하나의 글꼴과 그 형식이 구성되었으며, Satori가 지원하는 형식이라고 가정하고 정적 파일 엔드포인트에서 오픈 그래프 이미지를 생성합니다:
import type { APIRoute } from "astro";import { fontData } from "astro:assets";import { outDir } from "astro:config/server";import { readFile } from "node:fs/promises";import satori from "satori";import { html } from "satori-html";import sharp from "sharp";
export const GET: APIRoute = async (context) => { const fontPath = fontData["--font-roboto"][0]?.src[0]?.url;
if (fontPath === undefined) { throw new Error("Cannot find the font path."); }
const data = import.meta.env.DEV ? await fetch(new URL(fontPath, context.url.origin)).then(async (res) => res.arrayBuffer()) : await readFile(new URL(`.${fontPath}`, outDir));
const svg = await satori( html`<div style="color: black;">hello, world</div>`, { width: 600, height: 400, fonts: [ { name: "Roboto", data, weight: 400, style: "normal", }, ], }, );
const pngBuffer = await sharp(Buffer.from(svg)) .resize(600, 400) .png() .toBuffer();
return new Response(new Uint8Array(pngBuffer), { headers: { "Content-Type": "image/png", }, });};세부적인 글꼴 구성
섹션 제목: “세부적인 글꼴 구성”글꼴 패밀리는 굵기 및 스타일과 같은 속성(예: weights: [500, 600] 및 styles: ["normal", "bold"])의 조합으로 정의되지만, 이 중 특정 조합만 다운로드하고 싶을 수 있습니다.
다운로드할 글꼴 파일을 더 세부적으로 제어하려면, 동일한 글꼴(즉, 동일한 cssVariable, name, provider 속성)을 다른 조합으로 여러 번 지정할 수 있습니다. Astro는 결과를 병합하고 필요한 파일만 다운로드합니다. 예를 들어, 일반 500과 600을 다운로드하면서 이탤릭 500만 다운로드하는 것이 가능합니다.
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [ { name: "Roboto", cssVariable: "--roboto", provider: fontProviders.google(), weights: [500, 600], styles: ["normal"] }, { name: "Roboto", cssVariable: "--roboto", provider: fontProviders.google(), weights: [500], styles: ["italic"] } ]});폰트 API의 캐싱 구현은 개발 환경에서는 실용적이고 프로덕션 환경에서는 효율적이도록 설계되었습니다. 빌드 중에는 폰트 파일이 _astro/fonts 출력 디렉터리로 복사되어 정적 자산의 HTTP 캐싱(일반적으로 1년) 혜택을 받을 수 있습니다.
개발 환경에서 캐시를 지우려면 .astro/fonts 디렉터리를 제거하세요. 빌드 캐시를 지우려면 node_modules/.astro/fonts 디렉터리를 제거하세요.
Astro의 폰트 기능은 유연한 구성 옵션을 기반으로 합니다. 프로젝트의 폰트 구성은 단순화된 예시와 다를 수 있으므로, 프로덕션 환경에서 다양한 폰트 구성이 어떻게 보이는지 보여주기 위해 다음 예시가 제공됩니다.
import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({ fonts: [ { name: "Roboto", cssVariable: "--font-roboto", provider: fontProviders.google(), // 기본 포함: // weights: [400] , // styles: ["normal", "italic"], // subsets: ["latin"], // fallbacks: ["sans-serif"], // formats: ["woff2"], }, { name: "Inter", cssVariable: "--font-inter", provider: fontProviders.fontsource(), // 실제로 사용되는 굵기를 지정합니다. weights: [400, 500, 600, 700], // 실제로 사용되는 스타일을 지정합니다. styles: ["normal"], // 페이지에서 사용되는 문자 전용 글꼴 파일만 다운로드합니다. subsets: ["latin", "cyrillic"], // 더 많은 글꼴 형식을 다운로드합니다. formats: ["woff2", "woff"], }, { name: "JetBrains Mono", cssVariable: "--font-jetbrains-mono", provider: fontProviders.fontsource(), // 페이지에서 사용되는 문자 전용 글꼴 파일만 다운로드합니다. subsets: ["latin", "latin-ext"], // 의도한 모양과 일치하는 대체 글꼴 패밀리를 사용합니다. fallbacks: ["monospace"], }, { name: "Poppins", cssVariable: "--font-poppins", provider: fontProviders.local(), options: { // 굵기와 스타일이 지정되지 않았으므로 // Astro가 각 변형에 대해 이를 추론하려고 시도합니다. variants: [ { src: [ "./src/assets/fonts/Poppins-regular.woff2", "./src/assets/fonts/Poppins-regular.woff", ] }, { src: [ "./src/assets/fonts/Poppins-bold.woff2", "./src/assets/fonts/Poppins-bold.woff", ] }, ] } } ],});