icon안동민 개발노트

동적 메타데이터 생성


 Next.js에서 동적 라우트 및 데이터에 기반한 동적 메타데이터 생성은 SEO 최적화와 사용자 경험 향상에 중요한 역할을 합니다.

 이 절에서는 동적 메타데이터 생성 방법, SEO 최적화 전략, 그리고 성능 고려사항에 대해 알아보겠습니다.

generateMetadata 함수 사용법

 Next.js의 App Router에서는 generateMetadata 함수를 사용하여 동적 메타데이터를 생성할 수 있습니다.

export async function generateMetadata({ params, searchParams }, parent) {
  // 데이터 페칭 로직
  const product = await getProduct(params.id)
 
  return {
    title: product.name,
    description: product.description,
    openGraph: {
      images: [{ url: product.image }],
    },
  }
}

동적 라우트에서의 메타데이터 처리

 동적 라우트에서는 params를 사용하여 라우트 파라미터에 접근할 수 있습니다.

// app/blog/[slug]/page.js
export async function generateMetadata({ params }) {
  const post = await getPostBySlug(params.slug)
  
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [{ url: post.featuredImage }],
    },
  }
}

외부 데이터를 활용한 메타데이터 생성

 외부 API나 데이터베이스에서 가져온 데이터를 사용하여 메타데이터를 생성할 수 있습니다.

export async function generateMetadata({ params }) {
  const res = await fetch(`https://api.example.com/products/${params.id}`)
  const product = await res.json()
 
  return {
    title: product.name,
    description: product.description,
    openGraph: {
      images: [{ url: product.image }],
    },
  }
}

메타데이터 캐싱 전략

 성능 최적화를 위해 메타데이터를 캐싱할 수 있습니다. Next.js의 fetch API를 사용하면 자동으로 캐싱이 적용됩니다.

export async function generateMetadata({ params }) {
  const res = await fetch(`https://api.example.com/products/${params.id}`, { next: { revalidate: 3600 } })
  const product = await res.json()
 
  return {
    title: product.name,
    description: product.description,
  }
}

 이 예제에서는 메타데이터를 1시간(3600초)마다 재검증합니다.

6장 데이터 페칭과의 연관성

 동적 메타데이터 생성은 6장에서 다룬 데이터 페칭과 밀접하게 연관됩니다. generateMetadata 함수 내에서 데이터를 페칭하는 방식은 컴포넌트에서 데이터를 페칭하는 방식과 유사합니다. 두 경우 모두 Next.js의 자동 캐싱 및 재검증 기능을 활용할 수 있습니다.

// 메타데이터 생성을 위한 데이터 페칭
export async function generateMetadata({ params }) {
  const product = await getProduct(params.id)
  // ...
}
 
// 컴포넌트 렌더링을 위한 데이터 페칭
export default async function ProductPage({ params }) {
  const product = await getProduct(params.id)
  // ...
}

SEO 최적화 전략

  1. 고유하고 설명적인 제목과 설명 사용
  2. Open Graph 및 Twitter 카드 메타데이터 포함
  3. 구조화된 데이터(JSON-LD) 추가
  4. 동적 라우트에 대한 적절한 canonical URL 설정

성능 고려사항

  1. 불필요한 데이터 페칭 최소화
  2. 적절한 캐싱 전략 사용
  3. 메타데이터 생성 로직의 복잡성 관리

실습 : 블로그 포스트 페이지 동적 메타데이터 구현

 SEO 최적화된 동적 메타데이터를 가진 블로그 포스트 페이지를 구현해보겠습니다.

// app/blog/[slug]/page.js
import { getPostBySlug, getAllPosts } from '@/lib/api'
 
export async function generateMetadata({ params }) {
  const post = await getPostBySlug(params.slug)
  
  const ogImage = post.ogImage || post.coverImage || '/images/default-og.jpg'
 
  return {
    title: `${post.title} | My Tech Blog`,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      type: 'article',
      publishedTime: post.date,
      authors: [post.author.name],
      images: [
        {
          url: ogImage,
          width: 1200,
          height: 630,
          alt: post.title,
        },
      ],
    },
    twitter: {
      card: 'summary_large_image',
      title: post.title,
      description: post.excerpt,
      images: [ogImage],
    },
  }
}
 
export async function generateStaticParams() {
  const posts = await getAllPosts()
  
  return posts.map((post) => ({
    slug: post.slug,
  }))
}
 
export default async function BlogPostPage({ params }) {
  const post = await getPostBySlug(params.slug)
  
  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  )
}

 이 실습에서는 다음과 같은 SEO 최적화 전략을 구현했습니다.

  1. 동적으로 생성된 고유한 제목과 설명
  2. Open Graph 및 Twitter 카드 메타데이터 포함
  3. 게시 시간 및 저자 정보 추가
  4. 동적 OG 이미지 설정 (기본 이미지 폴백 포함)

 추가로, 구조화된 데이터(JSON-LD)를 포함하여 SEO를 더욱 강화할 수 있습니다.

export async function generateMetadata({ params }) {
  const post = await getPostBySlug(params.slug)
  
  // ... 기존 메타데이터 코드 ...
 
  return {
    // ... 기존 메타데이터 ...
    other: {
      'script:ld+json': {
        '@context': 'https://schema.org',
        '@type': 'BlogPosting',
        headline: post.title,
        description: post.excerpt,
        author: {
          '@type': 'Person',
          name: post.author.name,
        },
        datePublished: post.date,
        image: post.coverImage,
      },
    },
  }
}

 이 실습을 통해 SEO에 최적화된 동적 메타데이터를 생성하는 방법을 익힐 수 있습니다. 각 블로그 포스트에 대해 고유하고 관련성 있는 메타데이터를 제공함으로써 검색 엔진 랭킹을 향상시키고 소셜 미디어 공유 시 더 풍부한 정보를 제공할 수 있습니다.

 Next.js의 동적 메타데이터 생성 기능을 활용하면 각 페이지에 맞춤화된 SEO 최적화를 쉽게 구현할 수 있습니다. 데이터 페칭과 메타데이터 생성을 효율적으로 결합하여 성능을 최적화하고, 사용자와 검색 엔진 모두에게 가치 있는 정보를 제공할 수 있습니다.