C.W.K.
Stream
Lesson 06 of 08 · published

Metadata API

~20 min · metadata, OG image, SEO

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Static metadata

어떤 layout 또는 page 든 metadata object export. Framework 가 nested layout 의 metadata merge, page 가 우선. Title template compose: %s | My App.

Dynamic metadata

Tag 가 data 에 의존하는 route (blog post title, product name, user page) 위해 async generateMetadata({ params }) export.

Server-side generated Open Graph image

어떤 segment 든 opengraph-image.tsx drop 하면 Next.js 가 Vercel 의 Satori-based ImageResponse 통해 render. Design tool 없음, preflight 없음; OG image 를 React JSX 로 author.

Code

Static metadata + title template·tsx
// app/layout.tsx
import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: { template: '%s | My App', default: 'My App' },
  description: 'Built with Next.js',
  openGraph: {
    title: 'My App',
    description: 'Built with Next.js',
    url: 'https://myapp.com',
    siteName: 'My App',
    type: 'website',
  },
  twitter: { card: 'summary_large_image' },
};
Blog post 위한 dynamic metadata·tsx
// app/blog/[slug]/page.tsx
import type { Metadata } from 'next';

type Props = { params: Promise<{ slug: string }> };

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: { images: [post.ogImage] },
  };
}
JSX 로 dynamic OG image·tsx
// app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og';

export const size = { width: 1200, height: 630 };
export const contentType = 'image/png';

export default async function OG({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug);
  return new ImageResponse(
    (
      <div style={{
        fontSize: 64, background: '#0f172a', color: 'white',
        width: '100%', height: '100%', padding: 48, display: 'flex',
        flexDirection: 'column', justifyContent: 'flex-end',
      }}>
        <div>{post.title}</div>
      </div>
    ),
    { ...size }
  );
}

External links

Exercise

Root layout 에 title template 추가, blog page 한 개에 dynamic metadata, 같은 route 위해 opengraph-image.tsx. Twitter Card validator 로 OG card test.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.