IT

Next.js 15 元标签完全指南 —— 从 og:image 到 hreflang

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

Next.js 15 元标签完全指南 —— 从 og:image 到 hreflang

核心摘要

  • Next.js 15 通过基于 App Router 的 Metadata API,能够以声明式方式管理静态与动态元标签。
  • generateMetadata() 函数支持按页面自动生成动态 og:image、title 和 description。
  • Twitter Card、hreflang、canonical URL 以及结构化数据(JSON-LD),全部可以在单个文件中集中控制。
  • 元标签配置错误会直接导致社交分享预览异常和搜索排名下降,所以在部署前请务必使用 Meta Tag Checker 进行检查。

什么是 Next.js 15 的 Metadata API?

large gray ship sitting next body water
项目数值
Next.js 版本15
元标签管理方法Metadata API
动态元标签生成函数generateMetadata()
支持的元标签种类og:image、title、description、Twitter Card、hreflang、canonical URL、JSON-LD
元标签检查工具链接Meta Tag Checker

从 Next.js 13 开始引入的 App Router 提供了一个 Metadata API,用于替代传统的 组件写法。到了 Next.js 15,这个 API 变得更加精炼,允许你在 layout.tsxpage.tsx 文件中通过两种方式控制元标签:导出 metadata 对象,或使用 generateMetadata() 函数。

静态元数据

最简单的形式就是直接导出一个 metadata 对象。

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

export const metadata: Metadata = {
  title: 'Next.js 15 Meta Tag Guide',
  description: 'Everything about Next.js meta tags, from og:image to hreflang',
}

这种方式适合那些在构建时就已经确定内容的静态页面 —— 例如内容不经常变动的博客首页或关于页面。

动态元数据:generateMetadata()

对于内容会根据 URL 参数变化的页面 —— 比如博客文章或商品详情页 —— 请使用 generateMetadata() 函数。

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

type Props = {
  params: { slug: string }
}

export async function generateMetadata(
  { params }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  const post = await fetchPost(params.slug)

  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [{ url: post.ogImage, width: 1200, height: 630 }],
    },
  }
}

由于 generateMetadata() 在服务器端运行,它可以执行数据库查询和外部 API 调用。函数返回 Metadata 类型的值,Next.js 会自动将其注入到 标签中。


如何正确配置 og:image?

fighter jet sitting on aircraft carrier

Open Graph 图片就是在 KakaoTalk、Slack、Twitter 等社交平台上分享链接时所显示的预览图。如果配置不当,就会显示空白图片或者布局错乱,从而显著降低点击率。

基础 og:image 配置

tsx
export const metadata: Metadata = {
  openGraph: {
    title: 'Page Title',
    description: 'Page description',
    url: 'https://example.com/blog/my-post',
    siteName: 'Site Name',
    images: [
      {
        url: 'https://example.com/og/my-post.png',
        width: 1200,
        height: 630,
        alt: 'Post representative image',
      },
    ],
    locale: 'ko_KR',
    type: 'article',
  },
}

Next.js 中的动态 og:image 生成 —— ImageResponse

Next.js 15 支持使用 next/og 中的 ImageResponse 在服务器端动态渲染 OG 图片。整个设计可以完全用代码控制,不需要任何额外的图片编辑软件。

tsx
// app/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') ?? 'Default Title'

  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          fontSize: 60,
          background: '#0f172a',
          color: 'white',
          width: '100%',
          height: '100%',
          alignItems: 'center',
          justifyContent: 'center',
          padding: '40px',
        }}
      >
        {title}
      </div>
    ),
    { width: 1200, height: 630 }
  )
}

接着你可以在 generateMetadata() 内部引用这个端点。

tsx
images: [{ url: `https://example.com/og?title=${encodeURIComponent(post.title)}` }]

Twitter Card 配置

Twitter(现在叫 X)使用自己的元标签规范,但 Next.js 的 Metadata API 将其统一在 twitter 键下。

tsx
export const metadata: Metadata = {
  twitter: {
    card: 'summary_large_image',
    title: 'Page Title',
    description: 'Page description',
    creator: '@handle',
    images: ['https://example.com/og/my-post.png'],
  },
}

card 的可选值有 summarysummary_large_imageappplayer。对博客文章而言,summary_large_image 是最合适的选择。


如何用 hreflang 完成多语言 SEO

hreflang 标签用来告诉搜索引擎同一份内容的每个版本分别面向哪种语言和哪个地区。如果你同时运营韩文版和英文版网站,那么这一项必须配置。如果不配置,Google 可能会把不同语言的页面当作重复内容,从而降低它们的搜索可见度。

使用 alternates 配置 hreflang

tsx
export const metadata: Metadata = {
  alternates: {
    canonical: 'https://example.com/ko/blog/my-post',
    languages: {
      'ko-KR': 'https://example.com/ko/blog/my-post',
      'en-US': 'https://example.com/en/blog/my-post',
      'ja-JP': 'https://example.com/ja/blog/my-post',
    },
  },
}

基于这种配置,Next.js 会自动生成下面的 标签。

html
<link rel="canonical" href="https://example.com/ko/blog/my-post" />
<link rel="alternate" hreflang="ko-KR" href="https://example.com/ko/blog/my-post" />
<link rel="alternate" hreflang="en-US" href="https://example.com/en/blog/my-post" />
<link rel="alternate" hreflang="ja-JP" href="https://example.com/ja/blog/my-post" />

为什么 Canonical URL 的配置很重要

Canonical URL 标签用来告诉搜索引擎,当相同或相似的内容出现在多个 URL 时,「这个 URL 才是原版」。当分页、UTM 参数、www 与无 www 的差异等原因导致重复 URL 出现时,如果省略 canonical 标签,搜索排名信号就会被分摊到多个 URL 上。

tsx
alternates: {
  canonical: 'https://example.com/blog/my-post',
}

请使用绝对路径,并在整个网站中保持 HTTPS 和 www(带 www 或不带 www)的一致性。


用结构化数据(JSON-LD)获取 Rich Results

结构化数据可以让搜索结果获得 rich results,展示星级评分、作者、发布日期等额外信息。在 Next.js 中,推荐的做法是直接插入一个