Next.js
Next.js 블로그 글의 SEO 메타데이터를 어떻게 정하는지
title과 description을 대충 넣으면 검색 결과에서 보기 싫게 잘린다. 내가 지금 쓰는 기준을 정리했다.
블로그를 Next.js로 만들고 나서 SEO 메타데이터를 어떻게 채울지 한참 고민했다. 글마다 손으로 쓰는 게 맞는지, 자동 생성이 나은지, 길이는 얼마가 적당한지. 지금은 나름의 기준이 생겼다.
title 길이와 형식
검색 결과에서 title은 약 55~60자 정도가 잘리지 않는 한계다. 그 이상이면 …으로 잘린다. 나는 보통 아래 형식을 쓴다.
{글 제목} | turin's blog
Next.js App Router에서는 layout.tsx에 title.template을 설정하면 자동으로 뒤에 사이트 이름을 붙여준다.
// app/layout.tsx
export const metadata: Metadata = {
title: {
template: '%s | turin\'s blog',
default: 'turin\'s blog',
},
};
그러면 각 페이지에서는 글 제목만 넘기면 된다.
// app/posts/[slug]/page.tsx
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: post.title, // "PM2로 Node.js 앱 운영하기" → "PM2로 Node.js 앱 운영하기 | turin's blog"
description: post.excerpt,
};
}
description 작성 기준
description은 검색 결과에 항상 표시되는 건 아니지만, 구글이 내 텍스트를 쓸 때 이걸 우선 참고한다. 120~155자 사이, 글이 무슨 내용인지 구체적으로 한두 문장으로 쓴다.
좋은 예: PM2의 ecosystem.config.js 설정부터 자동 시작, 로그 rotate까지 처음 세팅할 때 해두면 좋은 것들을 정리했다.
나쁜 예: PM2에 대해 정리했습니다.
og:image 설정
Twitter/카카오톡 등으로 공유할 때 og:image가 없으면 링크가 밋밋하게 보인다. 동적으로 생성하려면 Next.js의 opengraph-image.tsx를 쓸 수 있다.
// app/posts/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og';
export default async function Image({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
return new ImageResponse(
<div style={{ fontSize: 40, background: '#0a0a0a', color: '#fff', width: '100%', height: '100%', display: 'flex', alignItems: 'center', padding: 60 }}>
{post.title}
</div>,
{ width: 1200, height: 630 }
);
}
canonical URL
cross-posting(dev.to 등)을 하거나 URL 구조가 바뀔 때를 대비해 canonical을 명시해두는 게 좋다.
return {
title: post.title,
description: post.excerpt,
alternates: {
canonical: `https://blog.example.com/posts/${post.slug}`,
},
};
확인할 때는 curl -s https://내블로그/posts/슬러그 | grep -i canonical로 실제 HTML에 들어갔는지 본다.