공유 카드의 임무는 하나입니다. 피드를 스크롤하는 사람이 1초 안에 제품이 무엇을 하는지 알 수 있어야 합니다. 효과적인 카드는 그라데이션 위에 로고만 띄우는 대신, 제품이 실제로 작동하는 모습(예: 서명된 제안서, 클라이언트가 확인할 수 있는 알림, 제안 가격)을 보여줍니다. 코드로 카드를 생성하면 브랜드와 동기화된 상태를 유지하고, 나중에 디자인 도구 없이도 변경할 수 있습니다.
1. 코드를 작성하기 전에 브랜드 수집
다음 순서대로 존재하는 자료를 읽으세요: 디자인 문서(DESIGN.md, PRODUCT.md, 스타일 가이드), CSS 토큰(globals.css, Tailwind @theme, CSS 사용자 정의 속성), 랜딩 페이지의 헤드라인과 서브라인, 로고(SVG 컴포넌트 또는 파일). 실제 16진수 색상 값과 실제 디스플레이 및 본문 글꼴을 사용하세요. 사이트와 다른 서체의 카드는 브랜드와 어울리지 않게 보입니다.
기존 설정(opengraph-image.*, og.png.*, 레이아웃의 og:image)을 찾아서 새로 추가하지 말고 확장하세요.
그런 다음 카드에 표시할 모형을 결정하세요. 사용자가 제품을 사용한 후 손에 쥐게 되는 것이 무엇인지 물어보세요(인보이스, 확인 이메일, 대시보드 타일, 영수증) 그리고 그것을 그리세요. 명확하지 않다면 한 문장으로 제안하고 사용자가 반대하지 않는 한 계속 진행하세요.
2. 카드 구성
사용자가 다르게 지정하지 않거나 기존 카드가 없다면 다음 레이아웃부터 시작하세요. 피드가 표시하는 작은 크기에서도 잘 읽힙니다.
| 영역 | 내용 |
|---|---|
| 캔버스 | 1200x630. 브랜드 배경색, 평면 또는 모형 쪽으로 부드러운 방사형 그라데이션. |
왼쪽 열, 약 620~660px 너비, 패딩 약 60px 0 60px 72px, justify-content: space-between으로 간격 조정 | 상단: 로고 마크와 34 |
| 오른쪽 | 브랜드 색상과 실제 데이터로 구성된 제품 모형. 2~4도 기울이고, 반대 방향으로 기울어진 악센트 색상의 뒷배경 카드를 뒤에 배치하며, 0 24px 48px -20px rgba(0,0,0,0.35)와 같은 부드러운 그림자를 적용. |
도움이 되는 작은 터치: 모형 위의 스탬프나 배지("결제됨", "확인됨"), 모형 모서리와 겹치는 주요 숫자가 적힌 슬립, 낮은 불투명도의 희미한 배경 선 작업.
카피:
- 헤드라인은 제품의 약속이며, 이상적으로 랜딩 페이지에서 사용하는 동일한 문구입니다. 구체적인 것이 재치 있는 것보다 낫습니다.
- 모형 데이터는 구체적이고 믿을 수 있어야 합니다 (
$1,510.00,38개 카드, 그럴듯한 고객 이름). 로렘 입숨이나$XX같은 플레이스홀더 텍스트는 제품이 미완성처럼 보이게 만듭니다. - 헤드라인의 한 구절을 악센트 색상으로 강조하는 것이 도움이 될 수 있습니다. 두 개 이상 강조하면 효과가 희석됩니다.
- 텍스트를 크게 유지하세요. 피드는 종종 카드를 실제 크기의 1/3로 표시하므로 약 18px 미만의 텍스트는 사라집니다.
3. 렌더링
Satori를 사용하세요. 이 라이브러리는 JSX 유사 트리를 SVG로 변환한 다음 PNG로 래스터화합니다. Next.js에서는 next/og로 제공됩니다. 다른 곳에서는 satori를 @resvg/resvg-js와 함께 사용하세요. 프레임워크별 연결(Next.js App Router, Astro 및 기타 정적 사이트용 일반 빌드 스크립트)에 대해서는 references/frameworks.md를 읽으세요.
Satori는 CSS의 하위 집합만 지원하며, 이러한 제한이 대부분의 실패 원인입니다:
- 글꼴은 렌더링 시 전달되는 실제 TTF, OTF 또는 WOFF 파일이어야 합니다. WOFF2는 작동하지 않으며 시스템 글꼴 폴백이 없습니다. 사용하는 2~3개의 굵기만 로드하세요. references/frameworks.md에서 파일을 가져오는 방법을 다룹니다.
- 둘 이상의 자식 요소가 있는 모든 요소에는
display: "flex"가 필요합니다. 그렇지 않으면 Satori가 오류를 발생시키므로 모든 상자의 기본값을 flex로 설정하세요. - CSS 그리드, CSS 변수,
calc()는 사용할 수 없습니다. 파일 상단의 작은 맵(const C = { ink: "#1c2128", ... })에 리터럴 색상을 넣으세요. - 텍스트는 자동으로 줄 바꿈됩니다. 마지막 줄에 단일 단어가 홀로 남거나 텍스트가 모형과 겹치지 않는지 주의하세요. 명시적으로 줄을 분할(span 열)하거나 너비와 크기를 조정하여 수정하세요.
whiteSpace: "nowrap"과flexShrink: 0을 함께 사용하면 가격과 라인 항목을 한 줄로 유지할 수 있습니다. position: "absolute"는 상대적 flex 부모 내에서 작동합니다. 뒷배경 카드, 스탬프 및 슬립에 사용하세요.- 인라인 SVG 경로는 잘 렌더링되므로 로고 이미지를 삽입하는 대신 로고의 SVG 경로를 재사용하세요. 로컬 래스터 이미지는 base64 데이터 URI로 변환하여 사용하세요.
4. 대체 텍스트와 태그
og:image:alt는 이미지가 실제로 보여주는 내용을 "브랜드: 모형이 보여주는 내용, 그리고 헤드라인." 형식으로 작성하세요. 예: "Acme Invoices: 결제됨 스탬프가 찍힌 $1,510.00 인보이스, 헤드라인: 현장을 떠나기 전에 돈을 받으세요."
페이지에는 절대 URL과 함께 다음이 필요합니다: og:title, og:description, og:image, og:image:width (1200), og:image:height (630), og:image:alt, twitter:card는 summary_large_image로 설정, twitter:image. 상대 경로의 og:image는 대부분의 언퍼러(unfurlers)가 이를 해석하지 못하기 때문에 카드가 표시되지 않는 가장 흔한 원인입니다.
5. 확인을 위해 눈으로 보기
PNG를 직접 보기 전에는 카드가 완성되었다고 말하지 마세요.
-
개발 서버를 시작하고, 이미지를 가져와 이미지 뷰어에서 열거나(이미지를 표시하는 파일 읽기 도구가 있다면 그 도구로) 확인하세요.
-
다음을 주의 깊게 살펴보세요: 홀로 남은 단어, 모형에 닿는 텍스트, 캔버스 가장자리에서 잘린 그림자, 고르지 않은 패딩, 폴백 글꼴(분명히 이상해 보입니다), 대비가 낮은 서브라인. 수정하고 깔끔해질 때까지 다시 렌더링하세요.
-
태그와 이미지를 함께 확인하세요:
python3 scripts/check_og.py http://localhost:3000/ --out /tmp/og-check.png이 스크립트는 모든 OG 및 Twitter 태그를 나열하고, 이미지를 가져와 1200x630 및 5MB 미만인지 확인하고, 상대 URL과 잘못된 카드 유형을 플래그 지정하며, 문제가 있으면 1을 반환하고 종료합니다. 저장된 PNG를 열어 예상한 이미지인지 확인하세요.
-
프로덕션 빌드를 실행하여 이미지가 여전히 생성되는지 확인하세요.
-
배포 후, 라이브 URL에 대해 검사기를 실행하세요. 사용자에게 Slack, LinkedIn 등은 언퍼을 캐시하므로 변경 전에 공유된 링크는 한동안 이전 카드를 유지할 수 있음을 알려주세요. LinkedIn의 Post Inspector는 새로고침을 강제합니다.
완료되면 사용자에게 PNG의 경로와 레이아웃 및 모형이 보여주는 내용을 설명하는 짧은 문단 하나를 제공하세요.