Next.js
Next.js에서 canonical URL이 소셜 미리보기를 망칠 때
Next.js의 canonical URL 설정이 잘못돼서 SNS 공유 시 미리보기가 깨지는 경우와 디버깅 과정을 다룬다.
블로그 글이나 상품 페이지를 카카오톡이나 페이스북에 공유할 때 미리보기가 제목, 이미지, 설명 대신 빈 화면이나 이전 페이지의 정보를 보여주는 일이 있다. 대부분은 canonical URL이 잘못 설정되거나 메타데이터가 제대로 렌더링되지 않았기 때문이다.
현재 상황 파악: 소셜 미리보기 검사
먼저 SNS에서 실제로 뭘 보는지 확인해야 한다:
# 네이버 SNS 정보 조회
curl -i 'https://yoursite.com/post/some-post-id'
# 응답 헤더에서 OpenGraph 메타 태그를 확인
curl -s 'https://yoursite.com/post/some-post-id' | grep -E 'og:|twitter:|canonical'
또는 Facebook의 공유 디버거(https://developers.facebook.com/tools/debug/)나 카카오톡의 메타 태그 검사 도구에 URL을 넣어서 어떤 정보를 읽는지 본다.
canonical URL의 역할과 주의사항
Canonical URL은 "이 페이지의 정식 주소는 이것이다"라고 검색 엔진과 SNS에 알려준다:
// pages/post/[id].js
import Head from 'next/head';
export default function Post({ post }) {
return (
<>
<Head>
<link rel="canonical" href={`https://yoursite.com/post/${post.id}`} />
<meta property="og:url" content={`https://yoursite.com/post/${post.id}`} />
<meta property="og:title" content={post.title} />
<meta property="og:description" content={post.excerpt} />
<meta property="og:image" content={post.image} />
</Head>
<article>{post.content}</article>
</>
);
}
Canonical URL과 og:url이 다르면 SNS가 혼란스러워한다.
로컬과 운영의 도메인 차이 확인
로컬에서는 http://localhost:3000이고 운영에서는 https://yoursite.com이면, 로컬 테스트할 때 미리보기가 제대로 나올 수 없다. 환경 변수로 도메인을 관리하자:
# .env.local
NEXT_PUBLIC_BASE_URL=http://localhost:3000
# .env.production
NEXT_PUBLIC_BASE_URL=https://yoursite.com
그리고 코드에서 사용:
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
<link rel="canonical" href={`${baseUrl}/post/${post.id}`} />
동적 경로에서 URL 생성 실수
동적 라우트를 쓸 때 URL을 잘못 만드는 경우가 많다:
// ❌ 잘못된 예
const url = `/post/${id}`; // 상대 경로
// ✓ 올바른 예
const url = `${process.env.NEXT_PUBLIC_BASE_URL}/post/${id}`; // 절대 URL
SNS 플랫폼은 절대 URL을 기대한다.
빌드 후 실제 HTML 확인
Next.js의 정적 생성(Static Generation)을 쓰면, 빌드 시점에 HTML이 생성된다. 빌드 후 생성된 파일을 직접 확인해보자:
npm run build
cat .next/server/pages/post/[id].html | head -100
OG 메타 태그가 제대로 있는지 보자. 없다면 Next.js가 렌더링하지 못한 것이다.
getStaticProps와 메타데이터
SSG(정적 생성)를 쓰는 경우, getStaticProps에서 데이터를 가져온 후에야 메타데이터를 만들 수 있다:
export async function getStaticProps({ params }) {
const post = await fetchPost(params.id);
return {
props: { post },
revalidate: 60 // ISR: 60초마다 재검증
};
}
export default function Post({ post }) {
return (
<Head>
<meta property="og:title" content={post.title} />
<meta property="og:description" content={post.excerpt} />
<meta property="og:image" content={post.image} />
<meta property="og:url" content={`https://yoursite.com/post/${post.id}`} />
</Head>
);
}
최종 검증: 배포 후 확인
배포 후 실제 URL을 검사 도구에 넣어서 확인하자:
# 1. 메타 태그 직접 확인
curl -s 'https://yoursite.com/post/abc123' | grep -A 5 'og:'
# 2. OpenGraph 이미지가 실제로 접근 가능한지
curl -i 'https://yoursite.com/images/post-image.jpg'
# 3. SNS 공유 디버거로 재크롤링
# Facebook: https://developers.facebook.com/tools/debug/
# 네이버: https://searchadvisor.naver.com/tools/sitecheck
Canonical URL이 정확하고 모든 메타 태그가 잘 렌더링되면, SNS 미리보기도 자동으로 개선된다. 특히 이미지 URL은 절대 경로여야 SNS가 인식할 수 있다.