Next.js如何动态为页面各语言区域版本头部添加hreflang标签
这个需求完全可以在 Next.js 中动态实现,以下是具体实现方案:
前置准备
先统一配置多语言相关的通用参数,避免重复代码,可新建 config/locales.js 文件:
// 支持的语言列表 export const locales = ['en', 'de', 'nl']; // 默认语言 export const defaultLocale = 'en'; // 站点域名 export const siteUrl = 'https://WEBSITE_URL'; // 各页面对应不同语言的路径映射 export const pathTranslations = { // 首页路径映射 '/': { en: '/', de: '/de', nl: '/nl' }, // 关于我们页面路径映射 '/about-us': { en: '/about-us', de: '/de/über-uns', nl: '/nl/over-ons' }, // 其他页面按需补充即可 };
分路由方案实现
1. App Router 版本(Next.js 13+)
直接在根 layout 中通过 generateMetadata 方法全局生成 hreflang 标签:
import { locales, siteUrl, pathTranslations, defaultLocale } from '@/config/locales'; export async function generateMetadata({ params }) { // 获取当前访问的页面路径 const currentPath = params.path ?? '/'; // 匹配当前页面对应各语言的路径,无匹配时回退到首页 const currentPathMap = pathTranslations[currentPath] ?? pathTranslations['/']; return { alternates: { // 自动生成所有语言版本的alternate链接 languages: Object.fromEntries( locales.map(lang => [lang, `${siteUrl}${currentPathMap[lang]}`]) ), // 可选:添加x-default回退版本,指向默认语言页面 canonical: `${siteUrl}${currentPathMap[defaultLocale]}` } }; }
2. Pages Router 版本
在全局 _app.js 中通过 next/head 组件注入标签:
import Head from 'next/head'; import { useRouter } from 'next/router'; import { locales, siteUrl, pathTranslations, defaultLocale } from '@/config/locales'; export default function App({ Component, pageProps }) { const router = useRouter(); const currentPath = router.pathname; const currentPathMap = pathTranslations[currentPath] ?? pathTranslations['/']; return ( <> <Head> {locales.map(lang => ( <link key={lang} rel="alternate" hrefLang={lang} href={`${siteUrl}${currentPathMap[lang]}`} /> ))} {/* 可选:添加x-default回退标签 */} <link rel="alternate" hrefLang="x-default" href={`${siteUrl}${currentPathMap[defaultLocale]}`} /> </Head> <Component {...pageProps} /> </> ); }
特殊场景适配
如果是动态路由页面(比如 /blog/[slug]),只需要在页面的 getStaticProps(Pages Router)或者 generateMetadata(App Router)中拿到动态参数后,拼接对应语言的完整路径即可。
如果你开启了 Next.js 内置的 i18n 路由能力,还可以直接通过路由实例自带的 locales、defaultLocale 等属性读取配置,不需要手动维护路径映射表。
内容的提问来源于stack exchange,提问作者Girgetto
相关产品推荐
相关产品推荐

