메타데이터 파일: opengraph-image 및 twitter-image
메타데이터 파일: opengraph-image 및 twitter-image | Next.js
섹션 제목: “메타데이터 파일: opengraph-image 및 twitter-image | Next.js”출처 URL: https://nextjs.org/docs/app/api-reference/file-conventions/metadata/opengraph-image
파일 시스템 규칙메타데이터 파일opengraph-image 및 twitter-image
opengraph-image 및 twitter-image
섹션 제목: “opengraph-image 및 twitter-image”마지막 업데이트 2026년 2월 20일
opengraph-image 및 twitter-image 파일 규칙은 라우트 세그먼트에 대해 Open Graph 및 Twitter 이미지를 설정할 수 있게 해줍니다.
이 규칙은 사용자가 사이트 링크를 소셜 네트워크나 메신저 앱에서 공유할 때 표시되는 이미지를 지정하는 데 유용합니다.
Open Graph와 Twitter 이미지를 설정하는 방법은 두 가지입니다.
이미지 파일(.jpg, .png, .gif)
섹션 제목: “이미지 파일(.jpg, .png, .gif)”세그먼트에 opengraph-image 또는 twitter-image 이미지 파일을 배치해 해당 라우트 세그먼트의 공유 이미지를 설정합니다.
Next.js는 파일을 평가하고 앱의 <head> 요소에 적절한 태그를 자동으로 추가합니다.
| 파일 규칙 | 지원 파일 형식 |
|---|---|
opengraph-image | .jpg, .jpeg, .png, .gif |
twitter-image | .jpg, .jpeg, .png, .gif |
opengraph-image.alt | .txt |
twitter-image.alt | .txt |
알아두면 좋아요 :
twitter-image파일 크기는 5MB를,opengraph-image파일 크기는 8MB를 초과하면 안 됩니다. 이미지 파일 크기가 이 한도를 넘으면 빌드가 실패합니다.
opengraph-image
섹션 제목: “opengraph-image”원하는 라우트 세그먼트에 opengraph-image.(jpg|jpeg|png|gif) 이미지 파일을 추가합니다.
twitter-image
섹션 제목: “twitter-image”원하는 라우트 세그먼트에 twitter-image.(jpg|jpeg|png|gif) 이미지 파일을 추가합니다.
opengraph-image.alt.txt
섹션 제목: “opengraph-image.alt.txt”opengraph-image.(jpg|jpeg|png|gif) 이미지와 같은 라우트 세그먼트에 해당 alt 텍스트인 opengraph-image.alt.txt 파일을 추가합니다.
opengraph-image.alt.txt
About Acmetwitter-image.alt.txt
섹션 제목: “twitter-image.alt.txt”twitter-image.(jpg|jpeg|png|gif) 이미지와 같은 라우트 세그먼트에 해당 alt 텍스트인 twitter-image.alt.txt 파일을 추가합니다.
twitter-image.alt.txt
About Acme코드로 이미지 생성(.js, .ts, .tsx)
섹션 제목: “코드로 이미지 생성(.js, .ts, .tsx)”실제 이미지 파일을 사용하는 것 외에도 코드로 이미지를 프로그래밍 방식으로 생성할 수 있습니다.
opengraph-image 또는 twitter-image 라우트를 만들고 기본 내보내기 함수에서 라우트 세그먼트의 공유 이미지를 생성하세요.
| 파일 규칙 | 지원 파일 형식 |
|---|---|
opengraph-image | .js, .ts, .tsx |
twitter-image | .js, .ts, .tsx |
알아두면 좋아요 :
- 기본적으로 생성된 이미지는 정적 최적화(빌드 시 생성 후 캐시)에 속하며, Dynamic API나 캐시되지 않은 데이터를 사용하지 않는 한 그렇습니다.
generateImageMetadata를 사용하면 하나의 파일에서 여러 이미지를 생성할 수 있습니다.opengraph-image.js와twitter-image.js는 특별한 Route Handler이며 Dynamic API나 동적 구성 옵션을 사용하지 않는 한 기본적으로 캐시됩니다.
가장 쉬운 이미지 생성 방법은 next/og의 ImageResponse API를 사용하는 것입니다.
app/about/opengraph-image.tsx
JavaScriptTypeScript
import { ImageResponse } from 'next/og' import { readFile } from 'node:fs/promises' import { join } from 'node:path'
// Image metadata export const alt = 'About Acme' export const size = { width: 1200, height: 630, }
export const contentType = 'image/png'
// Image generation export default async function Image() { // Font loading, process.cwd() is Next.js project directory const interSemiBold = await readFile( join(process.cwd(), 'assets/Inter-SemiBold.ttf') )
return new ImageResponse( ( // ImageResponse JSX element <div style={{ fontSize: 128, background: 'white', width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', }} > About Acme </div> ), // ImageResponse options { // For convenience, we can re-use the exported opengraph-image // size config to also set the ImageResponse's width and height. ...size, fonts: [ { name: 'Inter', data: interSemiBold, style: 'normal', weight: 400, }, ], } ) }Props
섹션 제목: “Props”기본 내보내기 함수는 다음 props를 받습니다.
params(선택 사항)
섹션 제목: “params(선택 사항)”루트 세그먼트부터 opengraph-image 또는 twitter-image가 배치된 세그먼트까지의 동적 라우트 매개변수 객체를 담은 객체로 해결되는 Promise입니다.
알아두면 좋아요 :
generateImageMetadata를 사용하면, 함수는generateImageMetadata에서 반환된 항목 중 하나의id값을 resolve하는idprop도 받습니다.
app/shop/[slug]/opengraph-image.tsx
JavaScriptTypeScript
export default async function Image({ params, }: { params: Promise<{ slug: string }> }) { const { slug } = await params // ... }| 라우트 | URL | params |
|---|---|---|
app/shop/opengraph-image.js | /shop | undefined |
app/shop/[slug]/opengraph-image.js | /shop/1 | Promise<{ slug: '1' }> |
app/shop/[tag]/[item]/opengraph-image.js | /shop/1/2 | Promise<{ tag: '1', item: '2' }> |
반환값
섹션 제목: “반환값”기본 내보내기 함수는 Blob | ArrayBuffer | TypedArray | DataView | ReadableStream | Response 중 하나를 반환해야 합니다.
알아두면 좋아요 :
ImageResponse는 이 반환 타입을 충족합니다.
구성 내보내기
섹션 제목: “구성 내보내기”opengraph-image 또는 twitter-image 라우트에서 alt, size, contentType 변수를 내보내 이미지 메타데이터를 선택적으로 구성할 수 있습니다.
| 옵션 | 타입 |
|---|---|
alt | string |
size | { width: number; height: number } |
contentType | string - 이미지 MIME 타입 |
alt
섹션 제목: “alt”opengraph-image.tsx | twitter-image.tsx
JavaScriptTypeScript
export const alt = 'My images alt text'
export default function Image() {}size
섹션 제목: “size”opengraph-image.tsx | twitter-image.tsx
JavaScriptTypeScript
export const size = { width: 1200, height: 630 }
export default function Image() {}contentType
섹션 제목: “contentType”opengraph-image.tsx | twitter-image.tsx
JavaScriptTypeScript
export const contentType = 'image/png'
export default function Image() {}라우트 세그먼트 구성
섹션 제목: “라우트 세그먼트 구성”opengraph-image 및 twitter-image는 Route Handler의 특수 형태이며, 페이지와 레이아웃과 동일한 라우트 세그먼트 구성 옵션을 사용할 수 있습니다.
외부 데이터 사용
섹션 제목: “외부 데이터 사용”이 예시는 params 객체와 외부 데이터를 사용해 이미지를 생성합니다.
알아두면 좋아요 : 기본적으로 이 생성된 이미지는 정적으로 최적화됩니다. 이 동작을 변경하려면 개별
fetchoptions또는 라우트 세그먼트 options을 구성할 수 있습니다.
app/posts/[slug]/opengraph-image.tsx
JavaScriptTypeScript
import { ImageResponse } from 'next/og'
export const alt = 'About Acme' export const size = { width: 1200, height: 630, } export const contentType = 'image/png'
export default async function Image({ params, }: { params: Promise<{ slug: string }> }) { const { slug } = await params const post = await fetch(`https://.../posts/${slug}`).then((res) => res.json() )
return new ImageResponse( ( <div style={{ fontSize: 48, background: 'white', width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', }} > {post.title} </div> ), { ...size, } ) }로컬 에셋과 함께 Node.js 런타임 사용
섹션 제목: “로컬 에셋과 함께 Node.js 런타임 사용”다음 예시는 Node.js 런타임을 사용해 파일 시스템에서 로컬 이미지를 가져온 뒤 <img>의 src 속성에 base64 문자열 또는 ArrayBuffer로 전달합니다. 로컬 에셋은 예제 소스 파일이 아니라 프로젝트 루트 기준으로 배치하세요.
app/opengraph-image.tsx
JavaScriptTypeScript
import { ImageResponse } from 'next/og' import { join } from 'node:path' import { readFile } from 'node:fs/promises'
export default async function Image() { const logoData = await readFile(join(process.cwd(), 'logo.png'), 'base64') const logoSrc = `data:image/png;base64,${logoData}`
return new ImageResponse( ( <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', }} > <img src={logoSrc} height="100" /> </div> ) ) }<img> 요소의 src 속성에 ArrayBuffer를 전달하는 것은 HTML 명세에 포함되지 않습니다. next/og에서 사용하는 렌더링 엔진은 이를 지원하지만, TypeScript 정의는 명세를 따르므로 이 기능을 사용하려면 @ts-expect-error 지시문이나 유사한 처리가 필요합니다.
app/opengraph-image.tsx
JavaScriptTypeScript
import { ImageResponse } from 'next/og' import { join } from 'node:path' import { readFile } from 'node:fs/promises'
export default async function Image() { const logoData = await readFile(join(process.cwd(), 'logo.png')) const logoSrc = Uint8Array.from(logoData).buffer
return new ImageResponse( ( <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', }} > {/* @ts-expect-error Satori accepts ArrayBuffer/typed arrays for <img src> at runtime */} <img src={logoSrc} height="100" /> </div> ) ) }버전 기록
섹션 제목: “버전 기록”| Version | Changes |
|---|---|
v16.0.0 | params가 이제 객체로 해석되는 프로미스입니다. |
v13.3.0 | opengraph-image와 twitter-image가 도입되었습니다. |