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

Vercel部署Next.js应用:getServerSideProps无法加载i18nexus翻译值

问题:Vercel部署后next-i18next + i18nexus翻译失效,仅显示键名

开发环境下用next-i18next配合i18nexus做多语言完全正常,但部署到Vercel后,所有翻译内容都只显示键名,加载不出实际翻译值。当前项目用getServerSideProps获取翻译数据,因为[id]组件的需求,没法改用getStaticProps(不需要配置getStaticPaths)。

相关配置代码

next-i18next.config.js

module.exports = {
   i18n: {
      locales: ['en', 'ru', 'ar', 'es'],
      defaultLocale: 'en'
   }
}

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: false,
  swcMinify: true,
  images: {
    domains: ["cdn.worldota.net"]
  },
  i18n: {
    locales: ['en', 'ru', 'ar', 'es'],
    defaultLocale: 'en',
  },
  env: {
    API_HOST: 'http://localhost:3000/api'
  },
}

module.exports = nextConfig

_app.tsx

function App({ Component, pageProps }: AppProps) {
//code

  return (
    <>
      <ReactReduxContext.Consumer>
        {({ store }) => (
          <PersistGate persistor={(store as any).__persistor} loading={<LoadingRouter />}>
            <Head>
              <link rel="icon" href={'./favicon.svg'} type="image/svg" />
            </Head>
            <div className='wrapper'>
              {loading && <LoadingRouter />}
              <Component {...pageProps} />
            </div>
          </PersistGate>
        )}
      </ReactReduxContext.Consumer>
    </>
  )
}

App.getInitialProps = wrapper.getInitialAppProps(store => async ({ ctx, Component }) => {
// store.dispatch(getUserData(userData.data.user)) и т.д.
   return {
    pageProps: Component.getInitialProps ? await Component.getInitialProps({ ...ctx, store 
   }) : {},
  }
})

index.tsx

const Home: NextPage<HomeType> = ({ locale }) => {
  const dispatch = useAppDispatch()

  useEffect(() => {
    dispatch(languageFunction(locale))
  }, [])

  return (
    <div className='shelters_housing'>
      <MainScreen />
      <div className='shelters_housing_flex'>
        <div className='shelters_housing_flex_container'>
          <TravelToEarn />
          <SearchByPlacementType />
          <PopularPlacesInRussia />
          <SubscribeNewsletter />
          <PopularHouses />
          <OurFavoriteDestinations />
        </div>
      </div>
      <SaveTimeAndMoney />
      <Footer />
    </div>
  )
}

export const getServerSideProps: GetStaticProps = async ({ locale }) => {
  return {
    props: {
      ...(await serverSideTranslations(locale!, ['main', 'footer', 'header', 'common', 'regions', 'discover'])),
      locale
    }
  }
}

解决方案

1. 确认翻译文件未丢失

i18nexus生成的翻译文件默认在public/locales目录,检查:

  • 目录下是否包含所有语言的子文件夹(en、ru、ar、es),每个子文件夹内是否有对应翻译JSON文件(如main.json)
  • .gitignore是否忽略了public/locales,若忽略会导致Vercel拉取代码时丢失翻译文件,直接显示键名

2. 统一i18n配置,避免重复定义

当前next-i18next.config.js和next.config.js均定义了i18n配置,易引发冲突。修改next.config.js,直接引入next-i18next.config的配置:

/** @type {import('next').NextConfig} */
const { i18n } = require('./next-i18next.config')

const nextConfig = {
  reactStrictMode: false,
  swcMinify: true,
  images: {
    domains: ["cdn.worldota.net"]
  },
  i18n, // 复用next-i18next的配置
  env: {
    API_HOST: 'http://localhost:3000/api'
  },
}

module.exports = nextConfig

3. 用appWithTranslation包裹App组件

你的_app.tsx未使用next-i18next的appWithTranslation高阶组件,导致全局翻译上下文未初始化,无法加载翻译。修改_app.tsx:

import { appWithTranslation } from 'next-i18next'
// 其他导入保持不变

function App({ Component, pageProps }: AppProps) {
// 原代码无需修改
}

App.getInitialProps = wrapper.getInitialAppProps(store => async ({ ctx, Component }) => {
  return {
    pageProps: Component.getInitialProps ? await Component.getInitialProps({ ...ctx, store }) : {},
  }
})

// 关键:用appWithTranslation包裹App组件后导出
export default appWithTranslation(App)

4. 修正getServerSideProps的类型错误

index.tsx中错误地将getServerSideProps标注为GetStaticProps类型,改为GetServerSideProps:

import { GetServerSideProps } from 'next'
// 其他导入不变

export const getServerSideProps: GetServerSideProps = async ({ locale }) => {
  return {
    props: {
      ...(await serverSideTranslations(locale!, ['main', 'footer', 'header', 'common', 'regions', 'discover'])),
      locale
    }
  }
}

5. 核对翻译键名完全匹配

检查i18nexus生成的JSON文件中的键名,与代码中useTranslation调用的键名是否完全一致(包括大小写、层级结构)。例如代码中使用t('main.welcome.title'),则JSON文件中需对应存在"welcome": {"title": "xxx"}的结构。

6. 动态拉取翻译需配置Vercel环境变量

若通过i18nexus API动态拉取翻译而非使用本地文件,需在Vercel环境变量中配置i18nexus的API密钥,并确保生产环境可正常访问该API。更推荐提前将翻译文件下载至本地public/locales,避免部署时网络问题导致翻译加载失败。


内容的提问来源于stack exchange,提问作者Стас Лабанов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:20:31