App Router에는 SEO 태그(<title>, <meta>, Open Graph 등)를 위한 내장 Metadata API가 있습니다. layout.tsx나 page.tsx에서 metadata를 export하면 Next.js가 올바른 <head> 태그를 렌더링합니다.
App Router에는 SEO 태그(<title>, <meta>, Open Graph 등)를 위한 내장 Metadata API가 있습니다. layout.tsx나 page.tsx에서 metadata를 export하면 Next.js가 올바른 <head> 태그를 렌더링합니다.
// app/about/page.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "About Us",
description: "Learn about our company and team.",
openGraph: {
title: "About Us",
images: ["/og-about.png"],
},
};
export default function About() { return <h1>About</h1>; }
Next.js는 export된 metadata 객체를 읽어 <title>, <meta name="description">, OG 태그 등을 생성합니다. 수동 <head> 편집이 필요 없습니다.
제목이 페칭된 콘텐츠(블로그 글, 상품)에 의존하는 페이지는 async generateMetadata 함수를 export하세요:
// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug); // 글 페칭
return {
title: post.title,
description: post.excerpt,
openGraph: { images: [post.coverImage] },
};
}
이는 서버에서 실행되며 각 동적 페이지가 정확하고 콘텐츠에 맞는 메타데이터를 갖게 해 줍니다. 동적 콘텐츠의 SEO 및 소셜 공유에 필수적입니다.
// app/layout.tsx — 기본값 + 제목 템플릿
export const metadata: Metadata = {
title: { default: "My Site", template: "%s | My Site" }, // 자식 제목이 "About | My Site"가 됨
};
레이아웃에 정의된 메타데이터는 자식 페이지와 병합되며(자식이 재정의 가능), 사이트 전반의 기본값을 한 번 설정하고 페이지별 값을 필요한 곳에 둘 수 있습니다. template은 사이트 이름을 자동으로 덧붙입니다.
app/favicon.ico, app/opengraph-image.png, app/robots.ts, app/sitemap.ts
특수 파일은 해당하는 메타데이터/라우트를 자동으로 생성합니다.
좋은 메타데이터는 SEO와 소셜 공유 미리보기를 좌우합니다.
Metadata API는 이를 선언적이고 타입 안전하게 만듭니다. 고정 페이지에는 정적 metadata, 데이터 기반 페이지에는 async generateMetadata, 레이아웃 수준의 기본값과 템플릿을 제공하여 수동 <head> 관리를 깔끔한 서버 렌더링 시스템으로 대체합니다.