개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Next.js Metadata — SEO를 위한 메타 태그 관리

2025년 5월 31일
Next.jsMetadataSEOOpenGraphgenerateMetadata

Next.js 13 App Router부터 <Head> 컴포넌트 대신 Metadata API를 사용해 메타 태그를 선언적으로 관리할 수 있다. 정적 페이지는 metadata 객체를 export하고, 동적 데이터가 필요한 페이지는 generateMetadata 함수로 서버에서 메타데이터를 생성한다. 두 방식 모두 Next.js가 자동으로 <head> 태그를 렌더링하므로 클라이언트 사이드 hydration 없이 SEO가 동작한다.

정적 Metadata export

페이지나 레이아웃 파일에서 metadata 객체를 named export하면 된다.

// app/page.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: '홈',
  description: '서비스 소개 페이지입니다.',
}

Metadata — Next.js가 제공하는 타입으로, 허용 가능한 메타 태그 필드를 타입 안전하게 정의한다.

title 템플릿

루트 레이아웃에 title template을 설정하면 하위 페이지의 title이 자동으로 조합된다.

// app/layout.tsx
export const metadata: Metadata = {
  title: {
    template: '%s | MySite',
    default: 'MySite',
  },
}
루트 layout    →  title.template = "%s | MySite"
  ├── /        →  title.default  = "MySite"
  ├── /about   →  title = "About"  →  "About | MySite"
  └── /blog/1  →  title = "포스트 제목"  →  "포스트 제목 | MySite"

하위 페이지에서 title만 문자열로 지정하면 template에 자동 삽입된다.

generateMetadata — 동적 메타데이터

블로그 포스트나 상품 상세 페이지처럼 URL 파라미터에 따라 메타데이터가 달라지는 경우 generateMetadata 함수를 사용한다.

// app/blog/[slug]/page.tsx
import type { Metadata } from 'next'

type Props = { params: { slug: string } }

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const post = await fetchPost(params.slug)

  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [{ url: post.thumbnail }],
    },
  }
}

generateMetadata — 서버 컴포넌트 컨텍스트에서 실행되며, 같은 fetch 요청은 Next.js가 자동으로 deduplicate한다.

OpenGraph & Twitter 카드

소셜 미디어 공유 미리보기를 위해 OpenGraph 메타데이터를 설정한다.

export const metadata: Metadata = {
  openGraph: {
    type: 'article',
    title: '포스트 제목',
    description: '포스트 요약',
    url: 'https://example.com/blog/post-slug',
    images: [
      {
        url: 'https://example.com/og/post-slug.png',
        width: 1200,
        height: 630,
      },
    ],
  },
  twitter: {
    card: 'summary_large_image',
    title: '포스트 제목',
    images: ['https://example.com/og/post-slug.png'],
  },
}

robots 설정

검색 엔진 크롤러의 인덱싱 동작을 robots 필드로 제어한다.

페이지 유형indexfollow
공개 콘텐츠truetrue
로그인 필요falsefalse
임시 페이지falsetrue
export const metadata: Metadata = {
  robots: {
    index: false,
    follow: false,
  },
}

robots.txt 파일 대신 페이지 단위로 세밀하게 제어할 수 있다는 점이 Metadata API의 강점이다. layout.tsx에 기본값을 두고 특정 페이지에서만 override하는 패턴이 유지보수에 유리하다.

← 이전 글Next.js Image Optimization — 이미지를 자동 최적화하는 방법
다음 글 →Next.js Middleware — 요청 처리 전에 실행되는 함수