IT

Next.js 15 メタタグ完全ガイド — og:imageからhreflangまで

USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。

Next.js 15 メタタグ完全ガイド — og:imageからhreflangまで

Next.js 15 のメタデータシステム

large gray ship sitting next body water

Next.js 15ではApp RouterのMetadata APIを使ってメタタグを管理する。従来のPages Routerで使っていたnext/headコンポーネントは不要になり、より宣言的でTypeScript完全対応のアプローチが可能だ。

静的メタデータの設定

fighter jet sitting on aircraft carrier

シンプルなページの場合、layout.tsxまたはpage.tsxからmetadataオブジェクトをexportする。

typescript
// app/layout.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {  title: 'MillionsCode — 韓国用語 韓国用語 韓国用語',  description: '18韓国用語 韓国用語 韓国用語 韓国用語 韓国用語 韓国用語 韓国用語 韓国用語',  keywords: ['韓国用語 韓国用語', 'SEO', 'calculation韓国用語', 'exchange rate'],  authors: [{ name: 'MillionsCode', url: 'https://millionscode.com' }],  openGraph: {  title: 'MillionsCode',  description: '韓国用語 韓国用語 韓国用語',  url: 'https://millionscode.com',  siteName: 'MillionsCode',  locale: 'ko_KR',  type: 'website',  },  twitter: {  card: 'summary_large_image',  title: 'MillionsCode',  description: '韓国用語 韓国用語 韓国用語',  },
}

動的メタデータの生成

ブログ記事やツールページなど、コンテンツによってメタタグが変わるページではgenerateMetadata()関数を使う。

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

interface Props {  params: Promise<{ id: string }>
}

export async function generateMetadata({ params }: Props): Promise<Metadata> {  const { id } = await params  const post = await getPost(id)  return {  title: `${post.title} | MillionsCode`,  description: post.description,  openGraph: {  title: post.title,  description: post.description,  url: `https://millionscode.com/blog/${post.slug}`,  images: [  {  url: `https://millionscode.com/api/og?title=${encodeURIComponent(post.title)}`,  width: 1200,  height: 628,  alt: post.title,  },  ],  type: 'article',  publishedTime: post.created_at,  modifiedTime: post.updated_at,  },  }
}

og:image の動的生成

Next.js 15では@vercel/og(ImageResponse)を使って動的OGイメージを生成できる。

typescript
// app/api/og/route.tsx
import { ImageResponse } from 'next/og'

export const runtime = 'edge'

export async function GET(request: Request) {  const { searchParams } = new URL(request.url)  const title = searchParams.get('title') ?? 'MillionsCode'  return new ImageResponse(  (  <div  style={{  background: '#0a0a0a',  width: '100%',  height: '100%',  display: 'flex',  flexDirection: 'column',  alignItems: 'center',  justifyContent: 'center',  padding: '60px',  }}  >  <div style={{ color: 'white', fontSize: 60, fontWeight: 'bold', textAlign: 'center' }}>  {title}  </div>  <div style={{ color: '#888', fontSize: 30, marginTop: 20 }}>  millionscode.com  </div>  </div>  ),  { width: 1200, height: 628 }  )
}

hreflang の設定(多言語対応)

多言語サイトではalternatesプロパティでhreflangを設定する。

typescript
export async function generateMetadata({ params }: Props): Promise<Metadata> {  const { lang, slug } = await params  const BASE = 'https://millionscode.com'  const LANGS = ['ko', 'en', 'ja', 'zh', 'es', 'fr', 'de', 'ar', 'hi', 'ru', 'id']  const languages: Record<string, string> = {}  for (const l of LANGS) {  languages[l] = l === 'ko'  ? `${BASE}/blog/${slug}`  : `${BASE}/${l}/blog/${slug}`  }  languages['x-default'] = `${BASE}/blog/${slug}`  return {  alternates: {  canonical: lang === 'ko' ? `${BASE}/blog/${slug}` : `${BASE}/${lang}/blog/${slug}`,  languages,  },  }
}

robots メタタグの設定

特定ページを検索エンジンにインデックスさせたくない場合はrobotsプロパティを使う。

typescript
export const metadata: Metadata = {  robots: {  index: true,  follow: true,  googleBot: {  index: true,  follow: true,  'max-video-preview': -1,  'max-image-preview': 'large',  'max-snippet': -1,  },  },
}

JSON-LD構造化データの挿入

メタタグとは別に、JSON-LDはScript要素として内に挿入する。

typescript
// ページの layout または page コンポーネント内
export default function BlogPage({ post }: { post: Post }) {  const jsonLd = {  '@context': 'https://schema.org',  '@type': 'BlogPosting',  headline: post.title,  description: post.description,  datePublished: post.created_at,  dateModified: post.updated_at,  author: {  '@type': 'Person',  name: 'MillionsCode',  url: 'https://millionscode.com/about',  },  }  return (  <>  <script  type="application/ld+json"  dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}  />  {/* ページコンテンツ */}  </>  )
}

まとめ

Next.js 15のMetadata APIは、型安全でシンプルな構文でSEOに必要なすべてのメタタグを管理できる。静的ページはmetadataオブジェクト、動的ページはgenerateMetadata()関数を使い分けることで、og:image・hreflang・JSON-LDまで一元管理できる。

🔧 Related Free Tools

関連