Next.js
Next.js 배포 후 메타데이터가 이상할 때
블로그 글의 제목, 설명, OG 이미지가 SNS에서 제대로 안 보인다면, 메타데이터 태그를 확인해야 한다.
블로그 글을 공유했는데 Facebook이나 Twitter에서 제목이 이상하게 보인다고 한다. 이럴 땐 메타데이터를 확인해야 한다.
배포된 페이지의 메타데이터 확인하기
# 공개 URL의 HTML 헤더 확인
curl -s https://example.com/blog/my-post | head -50
# 또는 grep으로 필터링
curl -s https://example.com/blog/my-post | grep -E '<title>|<meta|og:|twitter:'
HTML의 <head> 섹션에 다음이 있어야 한다:
<title>글의 제목</title>
<meta name="description" content="글의 요약" />
<meta property="og:title" content="글의 제목" />
<meta property="og:description" content="글의 요약" />
<meta property="og:image" content="이미지 URL" />
<meta property="og:url" content="https://example.com/blog/my-post" />
<meta name="twitter:card" content="summary_large_image" />
이 태그들이 없거나 잘못되면 SNS에서 제대로 표시되지 않는다.
Next.js에서 메타데이터 설정하기
// app/blog/[slug]/page.tsx
import { Metadata } from 'next';
export async function generateMetadata({
params,
}: {
params: { slug: string };
}): Promise<Metadata> {
const post = await fetchPost(params.slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
url: `https://example.com/blog/${post.slug}`,
images: [
{
url: post.ogImage,
width: 1200,
height: 630,
},
],
},
twitter: {
card: 'summary_large_image',
title: post.title,
description: post.excerpt,
images: [post.ogImage],
},
};
}
Pages Router를 쓰면:
// pages/blog/[slug].tsx
import Head from 'next/head';
export default function Post({ post }) {
return (
<>
<Head>
<title>{post.title}</title>
<meta name="description" content={post.excerpt} />
<meta property="og:title" content={post.title} />
<meta property="og:description" content={post.excerpt} />
<meta property="og:image" content={post.ogImage} />
<meta property="og:url" content={`https://example.com/blog/${post.slug}`} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={post.title} />
<meta name="twitter:description" content={post.excerpt} />
<meta name="twitter:image" content={post.ogImage} />
</Head>
<article>{post.content}</article>
</>
);
}
빌드 후 메타데이터 확인하기
# 로컬 개발 서버에서 확인
npm run dev
curl http://localhost:3000/blog/my-post | grep og:
# 빌드 후 프로덕션 빌드 서버에서 확인
npm run build
npm run start
curl http://localhost:3000/blog/my-post | grep og:
로컬에서는 괜찮은데 배포 후 이상하면 배포 환경의 설정을 확인해야 한다.
동적 페이지의 메타데이터
동적 페이지 [slug]에서 메타데이터를 가져올 때는 데이터 소스가 접근 가능한지 확인한다.
export async function generateMetadata({ params }) {
try {
const post = await fetchPost(params.slug);
// 데이터를 못 가져오면?
if (!post) {
return {
title: 'Post not found',
};
}
return {
title: post.title,
// ...
};
} catch (error) {
console.error('Failed to fetch post:', error);
return {
title: 'Error loading post',
};
}
}
getStaticProps에서 에러가 나면 메타데이터도 제대로 생성되지 않는다.
캐시 문제 확인하기
메타데이터는 동적이므로 캐시 헤더를 주의해야 한다.
# HTML의 캐시 헤더
curl -I https://example.com/blog/my-post
# Cache-Control이 no-cache인지 확인
# 또는 max-age가 짧은지 확인 (600초 이하)
HTML을 오래 캐시하면 메타데이터가 업데이트되지 않는다.
OG 이미지가 없다면
export async function generateMetadata({ params }) {
const post = await fetchPost(params.slug);
return {
openGraph: {
title: post.title,
images: post.ogImage || '/default-og-image.png', // 기본값 설정
},
};
}
OG 이미지가 없으면 기본 이미지를 사용하도록 설정하면 좋다.
배포 후 메타데이터 검증하기
# 페이스북 공유 디버거
https://developers.facebook.com/tools/debug/sharing/
# 트위터 카드 검증
https://cards-dev.twitter.com/validator
# 또는 curl로 직접 확인
curl -s https://example.com/blog/my-post | grep -E 'og:|twitter:' | head -20
배포 후 이 도구들로 메타데이터가 제대로 생성되는지 확인한다.
문제 해결 체크리스트
<head>섹션에 메타데이터 태그가 있는가?- og:image URL이 https://로 시작하는가?
- 이미지 파일이 실제로 존재하는가?
- 캐시 헤더가 no-cache 또는 짧은 max-age인가?
- 데이터 소스(API, 데이터베이스)가 빌드 시간에 접근 가능한가?
- 동적 페이지라면 에러 처리가 있는가?
이 항목들을 모두 확인하면 메타데이터 문제를 해결할 수 있다.