(준)공식 문서/Next.js

[ Next.js 15 공식 문서 ] Metadata and OG images (메타 데이터와 OG 이미지)

Je-chan 2025. 7. 20. 22:22

메타데이터와 OG 이미지

메타데이터 API는 SEO 개선과 웹 공유 기능을 위해 애플리케이션 메타데이터를 정의하는 데 사용할 수 있으며, 다음을 포함합니다:

  1. 정적 metadata 객체
  2. 동적 generateMetadata 함수
  3. 정적 또는 동적으로 생성되는 파비콘OG 이미지를 추가하는 데 사용할 수 있는 특별한 파일 규칙

위의 모든 옵션을 통해 Next.js는 자동으로 페이지에 대한 관련 <head> 태그를 생성하며, 브라우저의 개발자 도구에서 확인할 수 있습니다.

💡 실무 팁

메타데이터 설정은 SEO에 매우 중요합니다. 특히 블로그나 콘텐츠 사이트의 경우 각 페이지마다 고유한 제목과 설명을 설정하는 것이 검색 엔진 최적화에 큰 도움이 됩니다.

기본 필드

라우트에서 메타데이터를 정의하지 않더라도 항상 추가되는 두 개의 기본 meta 태그가 있습니다:

  • meta charset 태그: 웹사이트의 문자 인코딩을 설정합니다.
  • meta viewport 태그: 다양한 디바이스에 맞춰 조정할 수 있도록 웹사이트의 뷰포트 너비와 스케일을 설정합니다.
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

다른 메타데이터 필드는 Metadata 객체(정적 메타데이터용) 또는 generateMetadata 함수(생성된 메타데이터용)로 정의할 수 있습니다.

정적 메타데이터

정적 메타데이터를 정의하려면 정적 layout.js 또는 page.js 파일에서 Metadata 객체를 export합니다. 예를 들어, 블로그 라우트에 제목과 설명을 추가하려면:

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'My Blog',
  description: '...',
}

export default function Page() {}

사용 가능한 옵션의 전체 목록은 generateMetadata 문서에서 확인할 수 있습니다.

생성된 메타데이터

generateMetadata 함수를 사용하여 데이터에 의존하는 메타데이터를 fetch할 수 있습니다. 예를 들어, 특정 블로그 포스트의 제목과 설명을 가져오려면:

import type { Metadata, ResolvingMetadata } from 'next' type Props = { params: Promise<{ slug: string }> searchParams: Promise<{ [key: string]: string | string[] | undefined }> } export async function generateMetadata( { params, searchParams }: Props, parent: ResolvingMetadata ): Promise<Metadata> { const slug = (await params).slug // 포스트 정보 가져오기 const post = await fetch(`https://api.vercel.app/blog/${slug}`).then((res) => res.json() ) return { title: post.title, description: post.description, } } export default function Page({ params, searchParams }: Props) {}

스트리밍 메타데이터

동적으로 렌더링되는 페이지의 경우, generateMetadata 해결이 렌더링을 차단할 수 있다면, Next.js는 해결된 메타데이터를 별도로 스트리밍하고 준비되는 즉시 HTML에 주입합니다.

정적으로 렌더링되는 페이지는 메타데이터가 빌드 시간에 해결되므로 이 동작을 사용하지 않습니다.

데이터 요청 메모화

메타데이터와 페이지 자체에 대해 동일한 데이터를 가져와야 하는 경우가 있을 수 있습니다. 중복 요청을 피하기 위해 React의 cache 함수를 사용하여 반환 값을 메모화하고 데이터를 한 번만 가져올 수 있습니다.

import { cache } from 'react' import { db } from '@/app/lib/db' // getPost는 두 번 사용되지만 한 번만 실행됩니다 export const getPost = cache(async (slug: string) => { const res = await db.query.posts.findFirst({ where: eq(posts.slug, slug) }) return res })
🔍 알아두면 좋은 점

cache 함수를 사용하면 같은 데이터를 여러 번 호출해도 실제로는 한 번만 실행되어 성능상 이점을 얻을 수 있습니다. 특히 메타데이터 생성과 페이지 렌더링에서 같은 API를 호출할 때 유용합니다.

파일 기반 메타데이터

메타데이터를 위해 다음과 같은 특별한 파일들을 사용할 수 있습니다:

  • favicon.ico, apple-icon.jpg, icon.jpg
  • opengraph-image.jpg, twitter-image.jpg
  • robots.txt
  • sitemap.xml

이러한 파일들을 정적 메타데이터용으로 사용하거나 코드로 프로그래밍 방식으로 생성할 수 있습니다.

파비콘

파비콘은 북마크와 검색 결과에서 사이트를 나타내는 작은 아이콘입니다. 애플리케이션에 파비콘을 추가하려면 favicon.ico를 생성하고 app 폴더의 루트에 추가합니다.

💡 실무 팁

파비콘은 브랜드 인식에 중요한 역할을 합니다. 16x16, 32x32, 48x48 픽셀 등 여러 크기를 준비하고, 다크모드와 라이트모드에서 모두 잘 보이는 디자인을 선택하는 것이 좋습니다.

정적 Open Graph 이미지

Open Graph(OG) 이미지는 소셜 미디어에서 사이트를 나타내는 이미지입니다. 애플리케이션에 정적 OG 이미지를 추가하려면 app 폴더의 루트에 opengraph-image.png 파일을 생성합니다.

폴더 구조에서 더 깊은 곳에 opengraph-image.png를 생성하여 특정 라우트에 대한 OG 이미지를 추가할 수도 있습니다. 예를 들어, /blog 라우트에 특화된 OG 이미지를 생성하려면 blog 폴더 내부에 opengraph-image.jpg 파일을 추가합니다.

더 구체적인 이미지가 폴더 구조에서 위에 있는 모든 OG 이미지보다 우선합니다.

🔍 알아두면 좋은 점

jpeg, png, gif와 같은 다른 이미지 형식도 지원됩니다. OG 이미지의 권장 크기는 1200x630 픽셀입니다.

생성된 Open Graph 이미지

ImageResponse 생성자를 사용하면 JSX와 CSS를 사용하여 동적 이미지를 생성할 수 있습니다. 이는 데이터에 의존하는 OG 이미지에 유용합니다.

예를 들어, 각 블로그 포스트에 대한 고유한 OG 이미지를 생성하려면 blog 폴더 내부에 opengraph-image.ts 파일을 추가하고 next/og에서 ImageResponse 생성자를 import합니다:

import { ImageResponse } from 'next/og'
import { getPost } from '@/app/lib/data'

// 이미지 메타데이터
export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

// 이미지 생성
export default async function Image({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug)

  return new ImageResponse(
    (
      // ImageResponse JSX 요소
      <div
        style={{
          fontSize: 128,
          background: 'white',
          width: '100%',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        {post.title}
      </div>
    )
  )
}

ImageResponse는 flexbox와 절대 위치 지정, 사용자 정의 폰트, 텍스트 래핑, 중앙 정렬, 중첩 이미지를 포함한 일반적인 CSS 속성을 지원합니다.

💡 실무 팁
  • Vercel OG Playground에서 예제를 확인할 수 있습니다.
  • ImageResponse는 flexbox와 CSS 속성의 하위 집합만 지원합니다. 고급 레이아웃(예: display: grid)은 작동하지 않습니다.
  • OG 이미지는 소셜 미디어 공유 시 첫인상을 좌우하므로, 브랜드 색상과 로고를 포함하여 일관성 있는 디자인을 유지하는 것이 중요합니다.

API 참조

이 페이지에서 언급된 메타데이터 API에 대해 자세히 알아보세요:

  • generateMetadata - SEO 개선과 웹 공유 기능을 위해 Next.js 애플리케이션에 메타데이터를 추가하는 방법을 알아보세요.
  • generateViewport - generateViewport 함수에 대한 API 참조.
  • ImageResponse - ImageResponse 생성자에 대한 API 참조.
  • 메타데이터 파일 - 메타데이터 파일 규칙에 대한 API 문서.
  • favicon, icon, apple-icon - 파비콘, 아이콘, Apple 아이콘 파일 규칙에 대한 API 참조.
  • opengraph-image, twitter-image - Open Graph 이미지와 Twitter 이미지 파일 규칙에 대한 API 참조.
  • robots.txt - robots.txt 파일에 대한 API 참조.
  • sitemap.xml - sitemap.xml 파일에 대한 API 참조.
📖 원문 링크

이 문서의 원문은 Next.js 공식 문서에서 확인하실 수 있습니다.