dev.syw

metadata 객체와 동적 메타로 검색 최적화를 한다.

메타데이터와 SEO

검색 엔진과 SNS 공유에 잘 노출되려면 페이지마다 적절한 <title>, 설명, 미리보기 이미지가 필요합니다. App Router는 metadata 객체와 generateMetadata 함수로 이를 깔끔하게 다룹니다. 직접 <head> 를 만질 필요가 거의 없습니다.

학습 목표

  • 정적 metadata 객체로 제목·설명을 설정한다.
  • generateMetadata 로 동적 메타데이터를 만든다.
  • Open Graph로 SNS 공유 미리보기를 꾸민다.
  • sitemap, robots 로 크롤링을 돕는다.

정적 metadata 객체

layout.tsxpage.tsx 에서 metadata 를 내보내면 Next.js가 알아서 <head> 에 반영합니다.

// app/about/page.tsx
import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: '소개 | dev.syw.kr',
  description: '이 강좌 사이트를 소개합니다.',
};

export default function About() {
  return <h1>소개</h1>;
}

루트 레이아웃에 기본값을 두고, 각 페이지에서 덮어쓰는 식으로 조합됩니다.

title 템플릿

루트에서 title.template 을 정하면 하위 페이지 제목 뒤에 사이트 이름이 자동으로 붙습니다.

// app/layout.tsx
export const metadata: Metadata = {
  title: {
    default: 'dev.syw.kr',
    template: '%s | dev.syw.kr', // 하위에서 '소개' → '소개 | dev.syw.kr'
  },
};

💡 TIP — 하위 페이지에서는 title: '소개' 처럼 짧게만 쓰면 됩니다. %s 자리에 들어가 자동으로 완성됩니다.

동적 메타데이터 — generateMetadata

[slug] 처럼 내용이 가변인 페이지는 함수로 메타데이터를 만듭니다. params 를 받아 데이터를 읽고 제목을 구성합니다.

// app/blog/[slug]/page.tsx
import type { Metadata } from 'next';

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>;
}): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);
  return {
    title: post.title,
    description: post.excerpt,
  };
}

💡 TIPgenerateMetadata 안의 fetch 는 page 본문의 fetch 와 자동으로 합쳐집니다(5강의 memoization). 메타 때문에 같은 데이터를 두 번 받는 걱정은 안 해도 됩니다.

Open Graph — SNS 미리보기

카카오톡·트위터 등에서 링크를 공유할 때 보이는 카드입니다. openGraph 로 설정합니다.

export const metadata: Metadata = {
  title: 'Next.js 강좌',
  openGraph: {
    title: 'Next.js 강좌',
    description: 'App Router로 배우는 풀스택',
    images: ['/og/next.png'],
    type: 'article',
  },
};

sitemap 과 robots

검색 엔진이 사이트 구조를 알도록 돕는 파일도 코드로 만듭니다. app/sitemap.ts, app/robots.ts 를 두면 됩니다.

// app/sitemap.ts
import type { MetadataRoute } from 'next';

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    { url: 'https://dev.syw.kr', lastModified: new Date() },
    { url: 'https://dev.syw.kr/next/01-intro' },
  ];
}
// app/robots.ts
import type { MetadataRoute } from 'next';

export default function robots(): MetadataRoute.Robots {
  return {
    rules: { userAgent: '*', allow: '/' },
    sitemap: 'https://dev.syw.kr/sitemap.xml',
  };
}

⚠️ 주의metadata 객체와 generateMetadata 함수를 같은 파일에서 동시에 내보낼 수는 없습니다. 정적이면 객체, 가변이면 함수 중 하나만 쓰세요.

요약

  • metadata 객체로 제목·설명을 설정하고, title.template 으로 사이트 이름을 자동 부착한다.
  • 가변 페이지는 generateMetadata 함수로 동적 메타를 만든다.
  • openGraph 로 SNS 공유 미리보기를 꾸민다.
  • app/sitemap.ts, app/robots.ts 로 크롤링을 돕는다.

연습문제

  1. 루트 레이아웃에 title.template 을 설정하고, 하위 페이지에서 짧은 제목만 줘 보세요.
  2. [slug] 글 페이지에 generateMetadata 로 글 제목을 <title> 에 반영하세요.
  3. openGraph.images 를 설정하고, SNS 공유 시 미리보기가 나오는지 확인하세요.
  4. app/sitemap.ts 를 만들어 주요 페이지 URL을 나열해 보세요.

힌트 — 정적 메타는 객체, 동적 메타는 함수입니다. 둘을 한 파일에서 함께 export 하면 충돌하니 하나만 고르세요.

💡 연습문제 풀이

불러오는 중…

함께 보면 좋은 자료

댓글 0

Next.js” 강좌에 대한 댓글입니다.

댓글을 작성하려면 로그인이 필요합니다.