[프론트엔드] OG 태그 도입기

Administrator||조회수 22


Next.js App Router에서 동적 Open Graph 태그 구현하기

1. 도입의 필요성

작성한 포스트의 링크를 카카오톡 등 소셜에 공유했을 때, 단순한 파란색 주소만 표시되어 시각적으로 아쉬웠다. Open Graph(OG)는 바로 이 문제를 해결해줄 방법이었다.

💡 OG 태그(Open Graph Tag)란?

링크를 공유했을 때 해당 페이지의 제목, 설명, 대표 이미지를 담은 깔끔한 '미리보기 카드'를 만들어주는 메타 태그입니다. 이를 통해 콘텐츠의 첫인상을 효과적으로 전달하고, 클릭률과 공유율을 높일 수 있습니다.

OG 태그가 없다면 콘텐츠의 첫인상을 제대로 전달하기 어렵다. Deep Dive! 블로그의 공유 경험을 개선하고 더 많은 클릭을 유도하기 위해, 각 게시물 페이지마다 동적인 Open Graph 메타 태그를 생성하는 기능을 구현했다. 이 글은 Next.js App Router 환경에서 그 기능을 구현한 과정을 기록한 것이다.

alt text

2. 핵심 전략: generateMetadata 활용

Next.js App Router 환경에서는 generateMetadata 함수를 통해 이 문제를 아주 우아하게 해결할 수 있다. page.tsx 파일에서 이 함수를 export하면, Next.js는 페이지를 렌더링하기 전에 서버에서 이 함수를 먼저 실행시킨다.

이 함수의 가장 큰 장점은 async 함수로 만들 수 있다는 점이다. 즉, 함수 안에서 API를 호출하여 게시물 데이터를 미리 가져온 뒤, 그 동적인 데이터를 바탕으로 메타데이터를 생성해 HTML <head>에 삽입할 수 있다.

3. 코드 구현

구현의 핵심은 게시물 상세 페이지인 app/posts/[postId]/page.tsx 파일에 generateMetadata 함수를 작성하는 것이다.

// 파일 위치: app/posts/[postId]/page.tsx import { api } from "@/utils/api"; import type { Metadata, ResolvingMetadata } from 'next'; // ... (다른 import 및 타입 정의) export async function generateMetadata( { params }: Props, _parent: ResolvingMetadata ): Promise<Metadata> { try { const { postId } = params; const { post } = await api.fetchPostById(postId); if (!post) { return { title: '게시물을 찾을 수 없음' }; } const imageUrl = post.thumbnailUrl || 'https://blog.jungyu.store/default-thumbnail.webp'; return { title: post.title, description: post.summary, openGraph: { title: post.title, description: post.summary, url: `https://blog.jungyu.store/posts/${postId}`, siteName: 'Deep Dive!', images: [{ url: imageUrl, width: 1200, height: 630 }], type: 'article', }, twitter: { card: 'summary_large_image', title: post.title, description: post.summary, images: [imageUrl], }, }; } catch (error) { console.error(`Failed to generate metadata for post ${params.postId}:`, error); return { title: '서버 에러' }; } } export default async function PostDetailPage({ params }: Props) { // ... (페이지 컴포넌트 내용은 이전과 동일) }

코드의 핵심 포인트

  • 동적 데이터 조회: api.fetchPostById(postId)를 호출하여 현재 페이지에 맞는 게시물 정보를 서버에서 가져온다.
  • 이미지 Fallback: 게시물에 썸네일이 없는 경우를 대비해, 미리 준비해둔 기본 이미지를 사용하도록 설정했다. 덕분에 어떤 링크를 공유해도 이미지 누락이 발생하지 않는다.
  • 체계적인 정보 구성: openGraph 객체 안에 제목, 설명, 이미지, 공식 URL 등 표준에 맞는 정보들을 체계적으로 구성했다. type을 'article'로 지정하여 이 페이지가 하나의 '글'임을 명확히 했다.
  • 예외 처리: API 호출이 실패하거나 게시물이 없을 경우를 대비한 try...catch 로직으로 안정성을 높였다.

4. 올바르게 작동하는지 확인하기

코드를 작성한 후에는 반드시 검증이 필요하다.

4.1. 페이지 소스 확인

가장 간단한 방법은 브라우저에서 게시물 페이지에 접속한 뒤, '페이지 소스 보기'를 통해 HTML <head> 태그를 직접 확인하는 것이다.

<meta property="og:title" content="게시물의 실제 제목"> <meta property="og:description" content="게시물의 실제 요약..."> <meta property="og:image" content="게시물의 썸네일 URL 또는 기본 URL">

위와 같이 content 속성이 각 게시물의 내용에 맞게 동적으로 채워졌는지 확인했다.

4.2. 공식 디버거로 최종 점검

플랫폼이 내 페이지의 OG 태그를 어떻게 수집하는지 확인하는 가장 확실한 방법은 공식 디버거를 사용하는 것이다. 카카오톡에서 제공하는 공유 디버거에 배포된 게시물 URL을 입력하면, 실제 생성될 미리보기 카드를 미리 확인할 수 있었다.

alt text

5. 마무리하며

Next.js의 generateMetadata는 SEO와 소셜 공유 최적화를 매우 편리하게 만들어주는 기능이다. 간단한 구현만으로도 블로그 콘텐츠의 외부 공유 가치를 크게 높일 수 있었다. 이제 내 글들이 다른 플랫폼에서도 첫인상을 제대로 전달할 수 있게 되어 만족스럽다.

Administrator
Written by

Administrator

안녕하세요! Deep Dive! 블로그 제작자 입니다.

댓글을 불러오는 중...