문서
App Router 사용하기
오픈그래프 이미지 및 트위터 이미지

오픈그래프 이미지 및 트위터 이미지

opengraph-imagetwitter-image 파일 규칙을 사용하면 라우트 세그먼트에 대한 Open Graph 및 Twitter 이미지를 설정할 수 있습니다.

이들은 사용자가 귀하의 사이트 링크를 공유할 때 소셜 네트워크와 메시징 앱에 나타나는 이미지를 설정하는 데 유용합니다.

Open Graph 및 Twitter 이미지를 설정하는 두 가지 방법이 있습니다:

이미지 파일 (.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

opengraph-image

모든 라우트 세그먼트에 opengraph-image.(jpg|jpeg|png|gif) 이미지 파일을 추가합니다.

<head> output
<meta property="og:image" content="<generated>" />
<meta property="og:image:type" content="<generated>" />
<meta property="og:image:width" content="<generated>" />
<meta property="og:image:height" content="<generated>" />

twitter-image

모든 라우트 세그먼트에 twitter-image.(jpg|jpeg|png|gif) 이미지 파일을 추가합니다.

<head> output
<meta name="twitter:image" content="<generated>" />
<meta name="twitter:image:type" content="<generated>" />
<meta name="twitter:image:width" content="<generated>" />
<meta name="twitter:image:height" content="<generated>" />

opengraph-image.alt.txt

opengraph-image.(jpg|jpeg|png|gif) 이미지의 대체 텍스트로 사용될 opengraph-image.alt.txt 파일을 동일한 라우트 세그먼트에 추가합니다.

opengraph-image.alt.txt
About Acme
<head> output
<meta property="og:image:alt" content="About Acme" />

twitter-image.alt.txt

twitter-image.(jpg|jpeg|png|gif) 이미지의 대체 텍스트로 사용될 twitter-image.alt.txt 파일을 동일한 라우트 세그먼트에 추가합니다.

twitter-image.alt.txt
About Acme
<head> output
<meta property="twitter:image:alt" content="About Acme" />

코드를 사용하여 이미지 생성하기 (.js, .ts, .tsx)

실제 이미지 파일을 사용하는 것 외에도, 코드를 사용하여 프로그래밍 방식으로 이미지를 생성할 수 있습니다.

함수를 기본 내보내는 opengraph-image 또는 twitter-image 라우트를 생성하여 라우트 세그먼트의 공유 이미지를 생성할 수 있습니다.

파일 규칙지원되는 파일 형식
opengraph-image.js, .ts, .tsx
twitter-image.js, .ts, .tsx

알아두면 좋은 점

  • 기본적으로 생성된 이미지는 동적 함수나 캐시되지 않은 데이터를 사용하지 않는 한 정적으로 최적화됩니다(빌드 시 생성되고 캐시됨).
  • generateImageMetadata를 사용하여 동일한 파일에서 여러 이미지를 생성할 수 있습니다.
  • opengraph-image.jstwitter-image.js동적 함수동적 config 옵션을 사용하지 않는 한 기본적으로 캐시되는 특별한 Route Handler입니다.

이미지를 생성하는 가장 쉬운 방법은 next/ogImageResponse API를 사용하는 것입니다.

app/about/opengraph-image.tsx
import { ImageResponse } from "next/og";
 
export const runtime = "edge";
 
// 이미지 메타데이터
export const alt = "About Acme";
export const size = {
  width: 1200,
  height: 630,
};
 
export const contentType = "image/png";
 
// 이미지 생성
export default async function Image() {
  // 폰트
  const interSemiBold = fetch(
    new URL("./Inter-SemiBold.ttf", import.meta.url)
  ).then((res) => res.arrayBuffer());
 
  return new ImageResponse(
    (
      // ImageResponse JSX 요소
      <div
        style={{
          fontSize: 128,
          background: "white",
          width: "100%",
          height: "100%",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        About Acme
      </div>
    ),
    // ImageResponse 옵션
    {
      // 편의를 위해 내보낸 opengraph-image 크기 설정을
      // ImageResponse의 너비와 높이를 설정하는 데도 재사용할 수 있습니다.
      ...size,
      fonts: [
        {
          name: "Inter",
          data: await interSemiBold,
          style: "normal",
          weight: 400,
        },
      ],
    }
  );
}
app/about/opengraph-image.js
import { ImageResponse } from "next/og";
 
export const runtime = "edge";
 
// 이미지 메타데이터
export const alt = "About Acme";
export const size = {
  width: 1200,
  height: 630,
};
 
export const contentType = "image/png";
 
// 이미지 생성
export default async function Image() {
  // 폰트
  const interSemiBold = fetch(
    new URL("./Inter-SemiBold.ttf", import.meta.url)
  ).then((res) => res.arrayBuffer());
 
  return new ImageResponse(
    (
      // ImageResponse JSX 요소
      <div
        style={{
          fontSize: 128,
          background: "white",
          width: "100%",
          height: "100%",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        About Acme
      </div>
    ),
    // ImageResponse 옵션
    {
      // 편의를 위해 내보낸 opengraph-image 크기 설정을
      // ImageResponse의 너비와 높이를 설정하는 데도 재사용할 수 있습니다.
      ...size,
      fonts: [
        {
          name: "Inter",
          data: await interSemiBold,
          style: "normal",
          weight: 400,
        },
      ],
    }
  );
}
<head> output
<meta property="og:image" content="<generated>" />
<meta property="og:image:alt" content="About Acme" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />

Props

기본 내보내기 함수는 다음과 같은 props를 받습니다:

params (선택사항)

루트 세그먼트부터 opengraph-image 또는 twitter-image가 위치한 세그먼트까지의 동적 라우트 매개변수 객체를 포함하는 객체입니다.

app/shop/[slug]/opengraph-image.tsx
export default function Image({ params }: { params: { slug: string } }) {
  // ...
}
app/shop/[slug]/opengraph-image.js
export default function Image({ params }) {
  // ...
}
라우트URLparams
app/shop/opengraph-image.js/shopundefined
app/shop/[slug]/opengraph-image.js/shop/1{ slug: '1' }
app/shop/[tag]/[item]/opengraph-image.js/shop/1/2{ tag: '1', item: '2' }
app/shop/[...slug]/opengraph-image.js/shop/1/2{ slug: ['1', '2'] }

반환

기본 내보내기 함수는 Blob | ArrayBuffer | TypedArray | DataView | ReadableStream | Response를 반환해야 합니다.

알아두면 좋은 점: ImageResponse는 이 반환 타입을 만족합니다.

Config 내보내기

선택적으로 opengraph-image 또는 twitter-image 라우트에서 alt, size, 및 contentType 변수를 내보내어 이미지의 메타데이터를 구성할 수 있습니다.

옵션타입
altstring
size{ width: number; height: number }
contentTypestring - 이미지 MIME 타입

alt

opengraph-image.tsx | twitter-image.tsx
export const alt = "My images alt text";
 
export default function Image() {}
opengraph-image.js | twitter-image.js
export const alt = "My images alt text";
 
export default function Image() {}
<head> output
<meta property="og:image:alt" content="My images alt text" />

size

opengraph-image.tsx | twitter-image.tsx
export const size = { width: 1200, height: 630 };
 
export default function Image() {}
opengraph-image.js | twitter-image.js
export const size = { width: 1200, height: 630 };
 
export default function Image() {}
<head> output
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />

contentType

opengraph-image.tsx | twitter-image.tsx
export const contentType = "image/png";
 
export default function Image() {}
opengraph-image.js | twitter-image.js
export const contentType = "image/png";
 
export default function Image() {}
<head> output
<meta property="og:image:type" content="image/png" />

라우트 세그먼트 설정

opengraph-imagetwitter-image는 Pages와 Layouts와 동일한 라우트 세그먼트 구성 옵션을 사용할 수 있는 특수한 Route Handlers입니다.

예시

외부 데이터 사용하기

이 예시는 params 객체와 외부 데이터를 사용하여 이미지를 생성합니다.

알아두면 좋은 점: 기본적으로 이 생성된 이미지는 정적으로 최적화됩니다. 개별 fetch options 또는 라우트 세그먼트 옵션을 구성하여 이 동작을 변경할 수 있습니다.

app/posts/[slug]/opengraph-image.tsx
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: { slug: string } }) {
  const post = await fetch(`https://.../posts/${params.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,
    }
  );
}
app/posts/[slug]/opengraph-image.js
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 }) {
  const post = await fetch(`https://.../posts/${params.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,
    }
  );
}

로컬 리소스와 함께 Edge 런타임 사용하기

이 예시는 Edge 런타임을 사용하여 파일 시스템의 로컬 이미지를 가져와 ArrayBuffer<img> 요소의 src 속성에 전달합니다. 로컬 리소스은 예시 소스 파일 위치에 상대적으로 배치해야 합니다.

app/opengraph-image.tsx
import { ImageResponse } from "next/og";
 
export const runtime = "edge";
 
export default async function Image() {
  const logoSrc = await fetch(new URL("./logo.png", import.meta.url)).then(
    (res) => res.arrayBuffer()
  );
 
  return new ImageResponse(
    (
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <img src={logoSrc} height="100" />
      </div>
    )
  );
}
app/opengraph-image.js
import { ImageResponse } from "next/og";
 
export const runtime = "edge";
 
export default async function Image() {
  const logoSrc = await fetch(new URL("./logo.png", import.meta.url)).then(
    (res) => res.arrayBuffer()
  );
 
  return new ImageResponse(
    (
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <img src={logoSrc} height="100" />
      </div>
    )
  );
}

로컬 리소스과 함께 Node.js 런타임 사용하기

이 예시는 Node.js 런타임을 사용하여 파일 시스템의 로컬 이미지를 가져와 ArrayBuffer<img> 요소의 src 속성에 전달합니다. 로컬 리소스는 예시 소스 파일의 위치가 아닌 프로젝트의 루트에 상대적으로 배치해야 합니다.

app/opengraph-image.tsx
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",
        }}
      >
        <img src={logoSrc} height="100" />
      </div>
    )
  );
}
app/opengraph-image.js
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",
        }}
      >
        <img src={logoSrc} height="100" />
      </div>
    )
  );
}

버전 기록

버전변경 사항
v13.3.0opengraph-imagetwitter-image 도입.