如何在 Next.js 中根据语言动态生成 SEO 友好的 Metadata

本文详解如何利用 next.js 13+ 的 `generatemetadata` 函数,结合国际化路由(如 `/en-us/` 和 `/pt-br/`),为不同语言版本页面动态注入本地化标题、描述、关键词等元数据,显著提升多语言站点的搜索引擎可见性。

在 Next.js App Router 中,静态 metadata 对象无法访问路由参数(如语言标识 lang),因此不能直接用于多语言场景。正确做法是使用 generateMetadata 函数——它支持异步执行,并可接收 { params, searchParams } 等上下文对象,从而实现基于当前语言环境的元数据动态生成。

✅ 正确实现方式(推荐)

假设你的项目采用基于路径的国际化(Path-based i18n),路由结构为 app/[lang]/page.tsx(支持 en-US、pt-BR 等 locale),请按以下方式重构:

// app/[lang]/page.tsx
import { Metadata } from 'next';

const englishMetadata: Metadata = {
  title: {
    default: 'Brand',
    template: '%s | brand.xyz',
  },
  description: 'Premium events clothing and lifestyle apparel.',
  openGraph: {
    title: 'Brand',
    description: 'Premium events clothing and lifestyle apparel.',
    url: 'https://brand.xyz',
    siteName: 'Brand',
    type: 'website',
  },
  robots: {
    index: true,
    follow: true,
    googleBot: {
      index: true,
      follow: true,
      'max-video-preview': -1,
      'max-image-preview': 'large',
      'max-snippet': -1,
    },
  },
  icons: {
    shortcut: '/favicon.png',
  },
  keywords: 'events clothing, party wear, premium apparel',
};

const portugueseMetadata: Metadata = {
  title: {
    default: 'Brand',
    template: '%s | brand.xyz',
  },
  description: 'Roupas premium para eventos e estilo de vida.',
  openGraph: {
    title: 'Brand',
    description: 'Roupas premium para eventos e estilo de vida.',
    url: 'https://brand.xyz',
    siteName: 'Brand',
    type: 'website',
  },
  robots: {
    index: true,
    follow: true,
    googleBot: {
      index: true,
      follow: true,
      'max-video-preview': -1,
      'max-image-preview': 'large',
      'max-snippet': -1,
    },
  },
  icons: {
    shortcut: '/favicon.png',
  },
  keywords: 'eventos, vestuário, roupas festa, moda premium',
};

export async function generateMetadata({ params }: { params: { lang: string } }): Promise {
  // 安全校验:避免非法 lang 值导致未定义行为
  if (params.lang === 'pt-BR' || params.lang === 'pt-PT') {
    return portugueseMetadata;
  }
  return englishMetadata; // 默认回退至英文(也可扩展为多语言映射表)
}

export default function HomePage() {
  return (
    

Welcome to Brand

{/* 页面内容 */}
); }

⚠️ 关键注意事项

  • 不要在 layout.tsx 中硬编码 metadata:layout.tsx 是共享布局,不感知具体子路由语言参数;元数据应在最接近页面的层级(如 page.tsx 或 layout.tsx 的语言路径下)通过 generateMetadata 生成。
  • 支持动态值(如 CMS 数据):generateMetadata 支持 async,可安全调用 fetch 或 CMS SDK 获取实时翻译后的元数据:
    const data = await fetch(`https://cms.example.com/meta?lang=${params.lang}`).then(r => r.json());
    return { title: data.title, description: data.description };
  • SEO 最佳实践
    • 为每种语言设置唯一 hreflang 标签(Next.js 自动注入,前提是配置了 i18n 在 next.config.js);
    • openGraph.url 应使用完整 URL(含语言前缀,如 https://brand.xyz/pt-BR/),确保分享时链接准确;
    • keywords 已被主流搜索引擎弱化,但保留仍有助于部分垂直场景及内部搜索优化。

✅ 总结

generateMetadata 是 Next.js 多语言 SEO 的核心机制。它将元数据生成从静态声*级为上下文感知的函数式逻辑,使你既能复用结构化配置,又能精准匹配用户语言偏好与搜索引擎爬虫意图。配合正确的路由设计与国际化配置,即可构建真正符合全球 SEO 规范的现代化应用。