You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用next-intl国际化元数据,无需每页重复声明t变量

解决next-intl每页重复声明翻译变量的方案

当然有办法减少重复代码,下面是几个实用的方案:

1. 封装通用的元数据生成工具函数

把服务端的getTranslations逻辑抽成可复用的函数,页面只需传入命名空间即可生成国际化元数据:

// utils/i18n.ts
import { getTranslations } from 'next-intl/server';

export async function generatePageMetadata({ locale, namespace = 'Metadata' }) {
  const t = await getTranslations({ locale, namespace });
  return {
    title: t('title'),
    // 可扩展description等其他元数据字段
  };
}

页面中使用时:

import { useTranslations } from 'next-intl';
import { generatePageMetadata } from '@/utils/i18n';

export async function generateMetadata({ params: { locale } }) {
  return generatePageMetadata({ locale, namespace: 'UserProfileMetadata' });
}

export default function UserDetails({ user }) {
  const t = useTranslations('UserProfile');
  return (
    <section>
      <h2>{t('heading')}</h2>
    </section>
  );
}

2. 封装自定义Hook复用客户端翻译逻辑

对于客户端组件的翻译,可以封装一个自定义Hook,预设常用命名空间或灵活传参:

// hooks/usePageTranslations.ts
import { useTranslations } from 'next-intl';

export function usePageTranslations(namespace = 'Common') {
  return useTranslations(namespace);
}

页面中使用:

import { usePageTranslations } from '@/hooks/usePageTranslations';
import { generatePageMetadata } from '@/utils/i18n';

export async function generateMetadata({ params: { locale } }) {
  return generatePageMetadata({ locale, namespace: 'UserProfileMetadata' });
}

export default function UserDetails({ user }) {
  const t = usePageTranslations('UserProfile');
  return (
    <section>
      <h2>{t('heading')}</h2>
    </section>
  );
}

3. 用布局组件整合翻译逻辑(进阶)

如果页面有统一布局,可以把翻译逻辑整合到布局中,通过props或自定义Hook传递给页面组件:

// app/layout.tsx
import { getTranslations } from 'next-intl/server';
import { useTranslations } from 'next-intl';

// 服务端部分:为布局下的页面生成基础元数据
export async function generateMetadata({ params: { locale } }) {
  const t = await getTranslations({ locale, namespace: 'LayoutMetadata' });
  return {
    title: t('defaultTitle'),
  };
}

// 客户端布局组件
export default function RootLayout({ children, params: { locale } }) {
  const t = useTranslations('Common');
  return (
    <html lang={locale}>
      <body>
        <header>{t('header.title')}</header>
        <main>{children}</main>
      </body>
    </html>
  );
}

若需要页面级专属元数据,可让子页面导出自定义配置,在布局的generateMetadata中结合路由信息动态匹配命名空间。

额外优化:统一命名空间规范

如果页面内容和元数据的命名空间有规律(比如[PageName]和[PageName]Metadata),可进一步封装工具函数自动推导命名空间:

// utils/i18n.ts
import { getTranslations } from 'next-intl/server';

export async function generatePageMetadataForPage({ locale, pageName }) {
  const t = await getTranslations({ locale, namespace: `${pageName}Metadata` });
  return { title: t('title') };
}

页面中使用:

import { useTranslations } from 'next-intl';
import { generatePageMetadataForPage } from '@/utils/i18n';

export async function generateMetadata({ params: { locale } }) {
  return generatePageMetadataForPage({ locale, pageName: 'UserProfile' });
}

export default function UserDetails({ user }) {
  const t = useTranslations('UserProfile');
  return (
    <section>
      <h2>{t('heading')}</h2>
    </section>
  );
}

内容的提问来源于stack exchange,提问作者hb20007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:22:09