Next.js 13 App Router부터 <Head> 컴포넌트 대신 Metadata API를 사용해 메타 태그를 선언적으로 관리할 수 있다. 정적 페이지는 metadata 객체를 export하고, 동적 데이터가 필요한 페이지는 generateMetadata 함수로 서버에서 메타데이터를 생성한다. 두 방식 모두 Next.js가 자동으로 <head> 태그를 렌더링하므로 클라이언트 사이드 hydration 없이 SEO가 동작한다.
페이지나 레이아웃 파일에서 metadata 객체를 named export하면 된다.
// app/page.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '홈',
description: '서비스 소개 페이지입니다.',
}
Metadata — Next.js가 제공하는 타입으로, 허용 가능한 메타 태그 필드를 타입 안전하게 정의한다.
루트 레이아웃에 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에 자동 삽입된다.
블로그 포스트나 상품 상세 페이지처럼 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 메타데이터를 설정한다.
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 필드로 제어한다.
| 페이지 유형 | index | follow |
|---|---|---|
| 공개 콘텐츠 | true | true |
| 로그인 필요 | false | false |
| 임시 페이지 | false | true |
export const metadata: Metadata = {
robots: {
index: false,
follow: false,
},
}
robots.txt 파일 대신 페이지 단위로 세밀하게 제어할 수 있다는 점이 Metadata API의 강점이다. layout.tsx에 기본값을 두고 특정 페이지에서만 override하는 패턴이 유지보수에 유리하다.