Next.js Metadata란?
Next.js 13버전부터 도입된 App Router에서는 metadata API를 통해 웹 페이지의 메타데이터를 쉽게 관리할 수 있게 되었다.
메타데이터란 HTML 문서의 <head> 태그 내에 존재하는 정보들로, 웹 페이지의 제목, 설명, 키워드, Open Graph 태그 등을 포함.
이러한 메타데이터는 검색 엔진 최적화(SEO)에 중요한 역할을 하며, 소셜 미디어에서 공유될 때 웹 페이지가 어떻게 표시될지 결정한다.
Next.js의 metadata API는 개발자가 각 페이지 또는 레이아웃 컴포넌트에서 메타데이터를 직접 정의할 수 있게 해주어, 페이지별로 맞춤화된 메타데이터 설정이 가능하다.
특히 TypeScript와 함께 사용하면 타입 안정성을 보장받으면서 메타데이터를 관리할 수 있다는 장점이 있다.
Metadata의 종류와 사용법
Next.js에서는 크게 두 가지 방식으로 메타데이터를 정의할 수 있다!
- 정적 메타데이터
- 동적 메타데이터
정적 메타데이터는 빌드 시점에 결정되는 메타데이터로, layout.tsx 또는 page.tsx 파일 내에서 metadata 객체를 export하여 정의한다.
동적 메타데이터는 요청 시점에 결정되는 메타데이터로, generateMetadata 함수를 export하여 정의한다.
Next.js의 metadata API는 다양한 메타데이터 필드를 지원한다. 아래 예시를 함께 살펴보자.
- 기본 필드: title, description
- Open Graph 필드: openGraph
- Twitter 필드: twitter
- 아이콘 필드: icons
- 기타: robots, viewport, alternates 등
layout.tsx에서 정적 Metadata 설정하기
layout.tsx 파일에서 정적 메타데이터를 설정하는 것은 매우 간단하다.
아래 예시 코드를 통해 살펴보자.
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '내 Next.js 블로그',
description: 'Next.js와 TypeScript를 사용한 개인 기술 블로그입니다.',
keywords: ['Next.js', 'React', 'TypeScript', '웹개발'],
openGraph: {
title: '내 Next.js 블로그',
description: '개인 기술 블로그에 오신 것을 환영합니다',
url: 'https://my-blog.com',
siteName: '기술 블로그',
images: [
{
url: 'https://my-blog.com/og-image.jpg',
width: 1200,
height: 630,
alt: '블로그 미리보기 이미지',
},
],
locale: 'ko_KR',
type: 'website',
},
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="ko">
<body>{children}</body>
</html>
)
}
위 코드에서는 metadata 객체를 export하여 웹 사이트의 기본 메타데이터를 정의하고 있다.
title과 description 같은 기본 필드부터 openGraph 객체를 통한 소셜 미디어 공유 시 표시될 정보까지 설정하고 있다.
(TypeScript를 사용하므로 Metadata 타입을 import하여 타입 안정성을 확보했다.)
이렇게 layout.tsx에 설정된 메타데이터는 해당 레이아웃을 사용하는 모든 페이지에 적용된다.
만약 특정 페이지에서 이 메타데이터를 오버라이드하고 싶다면, 해당 페이지의 page.tsx 파일에서 다시 metadata를 export하면 된다.
동적 Metadata 생성하기
블로그 포스트나 제품 상세 페이지처럼 동적 라우팅을 사용하는 페이지에서는 페이지 내용에 따라 메타데이터도 동적으로 생성해야 할 필요가 있다.
이럴 때는 generateMetadata 함수를 사용한다.
import { Metadata, ResolvingMetadata } from 'next'
type Props = {
params: { slug: string }
}
export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
// params.slug에서 블로그 포스트 ID 등의 정보를 가져올 수 있다
const post = await fetchBlogPost(params.slug)
// 부모 메타데이터(layout.tsx에서 정의한 것 등)를 가져올 수도 있다
const previousImages = (await parent).openGraph?.images || []
return {
title: post.title,
description: post.excerpt,
openGraph: {
images: [
{
url: post.coverImage,
width: 1200,
height: 630,
alt: post.title,
},
...previousImages,
],
},
}
}
export default function BlogPost({ params }: Props) {
// 블로그 포스트 컴포넌트
return <div>...</div>
}
위 코드에서는 generateMetadata 함수를 사용하여 URL 파라미터(params.slug)를 기반으로 동적 메타데이터를 생성하고 있다.
이 함수는 비동기 함수로, API 호출 등을 통해 필요한 데이터를 가져올 수 있다.
또한 parent 파라미터를 통해 상위 레이아웃에서 정의한 메타데이터에 접근할 수도 있다.
🚨동적 메타데이터는 서버 컴포넌트에서만 사용할 수 있으며, 클라이언트 컴포넌트에서는 사용할 수 없다🚨
Metadata를 활용한 SEO 최적화
Next.js의 metadata API를 활용하면 SEO를 효과적으로 최적화할 수 있다.
주요 SEO 요소들을 설정하는 방법을 알아볼까?
import { Metadata } from 'next'
export const metadata: Metadata = {
title: '내 블로그 | 최신 프론트엔드 기술',
description: '최신 웹 개발 트렌드와 기술에 대한 정보를 제공하는 블로그입니다.',
keywords: ['Next.js', 'React', 'TypeScript', 'Frontend'],
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
canonical: 'https://my-blog.com',
alternates: {
canonical: 'https://my-blog.com',
languages: {
'en-US': 'https://my-blog.com/en',
'ko-KR': 'https://my-blog.com/ko',
},
},
verification: {
google: 'google-site-verification-code',
yandex: 'yandex-verification-code',
},
}
위 코드는 SEO에 중요한 여러 메타데이터 요소들을 설정하고 있다.
- robots 필드는 검색 엔진 크롤링 방식을 제어하고,
- canonical은 중복 콘텐츠 문제를 해결하며,
- alternates는 다국어 웹사이트에서 각 언어 버전의 URL을 지정한다.
- verification 필드는 Google Search Console 같은 서비스에 사이트 소유권을 증명하는 데 사용된다.
이처럼 Next.js의 metadata API는 SEO에 필요한 거의 모든 메타데이터를 간편하게 설정할 수 있는 방법을 제공한다.
File-based Metadata vs. Config-based Metadata
Next.js에서는 메타데이터를 설정하는 두 가지 방식이 있다
- 파일 기반(file-based)
- 설정 기반(config-based)
파일 기반 메타데이터는 특수한 파일명을 사용하여 메타데이터를 설정하는 방식이다.
예를 들어 아래와 같은 예시가 있다.
- favicon.ico, apple-icon.jpg, icon.jpg: 파비콘 및 앱 아이콘 설정
- opengraph-image.jpg, twitter-image.jpg: 소셜 미디어 공유 이미지
- robots.txt: 검색 엔진 크롤링 규칙
- sitemap.xml: 사이트맵
이러한 파일들을 특정 디렉토리에 배치하면 Next.js가 자동으로 인식하여 적절한 메타데이터로 변환한다.
반면, 설정 기반 메타데이터는 앞서 살펴본 것처럼 metadata 객체나 generateMetadata 함수를 통해 프로그래밍 방식으로 설정하는 방식이다.
두 방식은 각각 장단점이 있으며, 상황에 따라 적절히 조합하여 사용하는 것이 좋다고 생각한다.
내가 생각하는 적절한 조합은 아래와 같다!
정적인 아이콘이나 로봇 규칙은 파일 기반으로,
페이지별로 달라지는 제목이나 설명은 설정 기반으로 관리하기!!!
'Next.js' 카테고리의 다른 글
[Next.js] App Router에서 src 디렉토리 사용할거야??? (2) | 2025.03.22 |
---|---|
[Next.js] Turbopack? 뭐지? 개발 환경 속도를 향상시킨다고?!! (0) | 2025.03.20 |
[Next.js] Next.js + TypeScript에서의 라우팅 시 데이터 전달 방법 총정리 (0) | 2025.03.18 |
[Next.js] Next.js + TypeScript에서의 페이지 이동 방법 총정리 (0) | 2025.03.17 |
[Next.js] 'use client'와 React Hooks의 관계 - SSR과 CSR의 경계 이해하기 (0) | 2025.03.16 |