SVG 디자인: Satori + SVGO은(는) 무엇을 하나요?
2026-10 확인: satori 0.63, @resvg/resvg-js 2.6, svgo 4.1.
Satori — 마크업 → SVG
npm i satori @resvg/resvg-js
import satori from 'satori'
import { Resvg } from '@resvg/resvg-js'
import { readFile, writeFile } from 'node:fs/promises'
const font = await readFile('./Inter-Bold.ttf') // TTF, OTF, WOFF 또는 WOFF2
const svg = await satori(
<div style={{ display: 'flex', width: '100%', height: '100%', alignItems: 'center',
justifyContent: 'center', background: '#0b1020', color: 'white', fontSize: 96 }}>
Đủ 20/20
</div>,
{ width: 1920, height: 1080, fonts: [{ name: 'Inter', data: font, weight: 700, style: 'normal' }] },
)
const png = new Resvg(svg, { fitTo: { mode: 'width', value: 1920 } }).render().asPng()
await writeFile('title.png', png)
- JSX/React 없이 일반 객체 전달:
{ type: 'div', props: { style: {...}, children: '...' } }. - 텍스트가 있을 때 폰트는 필수입니다. 베트남어는 해당 글리프가 있는 폰트(Inter, Be Vietnam Pro, Noto Sans)가 필요합니다.
- 레이아웃: Flexbox, Grid (서브그리드/메이슨리 제외) 및 블록. CSS 하위 집합입니다 — JS, 애니메이션, 외부 스타일시트 없음; 인라인 스타일 사용.
- 이미지:
<img src>에 절대 URL 또는 데이터 URI 사용, 명시적width/height필요. - 텍스트는 기본적으로
<path>가 됩니다(이식성 좋지만 선택 불가).embedFont: false로<text>유지 가능. - 이모지: 누락된 세그먼트에 대한 이미지/폰트를 제공하려면
graphemeImages또는loadAdditionalAsset사용. - PNG 대안:
sharp(Buffer.from(svg)).png().
SVGO v4 — 최적화
npx svgo in.svg -o out.svg
npx svgo -f ./icons -o ./icons-min
// svgo.config.mjs
export default {
multipass: true,
plugins: [
{ name: 'preset-default', params: { overrides: {
// SVG가 애니메이션되거나 id/class로 스타일링될 때 유지:
cleanupIds: false, // 코드가 타겟팅하는 id를 이름 바꾸거나 제거함
collapseGroups: false, // 애니메이션 단위로 사용하는 <g>를 평탄화함
mergePaths: false, // 개별 애니메이션하는 경로를 병합함
convertShapeToPath: false, // <circle>/<rect>를 <path>로 변환 (r, cx, width 속성 사라짐)
} } },
'prefixIds', // 여러 SVG가 한 페이지에 인라인될 때 고유한 id 부여
],
}
- v4 변경사항:
removeViewBox와removeTitle이 더 이상 preset-default에 포함되지 않음 (원하면 이름으로 추가; 스케일링을 위해 viewBox 유지).removeScriptElement→removeScripts. 명명된 내보내기만:import { optimize } from 'svgo'; 브라우저 빌드는svgo/browser. - Node API:
const { data } = optimize(svgString, { multipass: true, plugins: [...] }). - 정적 아이콘의 경우 일반
preset-default로 충분합니다. 위의 override는 애니메이션 또는 스크립트된 SVG에만 필요합니다. - 애니메이션용 SVG를 최적화한 후, 애니메이션 코드가 사용하는 모든 선택자가 출력에 여전히 존재하는지 확인하세요.