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

Next.js中从Pages路由迁移至App路由时的getStaticProps({locale})适配问题

Next.js 13 App Router 中获取 locale 并适配 next-i18n 的问题

我正尝试将Next.js项目从Pages路由迁移至App Router,在适配Next 13的App Router页面时遇到了getStaticProps({locale})的问题。原Pages路由中getStaticProps默认会接收locale参数,但在App Router中不清楚该如何获取这个locale参数。


原Pages路由代码

import React from 'react';
import {message} from 'antd';
import {TFunction, I18n, useTranslation} from 'next-i18next';
import {NextPage} from 'next';
import {NextSeo} from 'next-seo';
import {useRouter} from 'next/navigation';
import {serverSideTranslations} from 'next-i18next/serverSideTranslations';

import Layout from '../../components/Layout';
import AuthorForm, {FormFields} from '../../components/Author/Form';

import {useCreateAuthor} from '../../service-hooks/resourceAuthor';

type InitialProps = Promise<{
  namespacesRequired: string[];
}>;

type Props = {
  t: TFunction;
  i18n: I18n;
};


const NewAuthor: NextPage<Props, InitialProps> = () => {
  const {t, i18n} = useTranslation(['common', 'form', 'admin', 'resource-types']);
  const router = useRouter();
  const {mutate: create, isLoading} = useCreateAuthor();

  return (
    <Layout defaultLanguage={i18n.language} tFunc={t}>
      <NextSeo title={t('form:new', {entity: t('admin:authors.label')})}/>
      <div className="pt-4">
        <AuthorForm tFunc={t} processLoading={isLoading} texts={AuthorFormTexts} onFinish={handleFinish}/>
      </div>
    </Layout>
  );
};

const getStaticProps = async function({locale}) {
  return {
    ...(await serverSideTranslations(locale, ['common', 'form', 'admin', 'resource-types'])),
    // 传递给页面组件的props
  };
}

export default NewAuthor;

尝试的App Router代码(无法获取locale)

我尝试使用异步函数替代,但无法获取locale参数:

import React from 'react';
import {message} from 'antd';
import {TFunction, I18n, useTranslation} from 'next-i18next';
import {NextPage} from 'next';
import {NextSeo} from 'next-seo';
import {useRouter} from 'next/navigation';
import {serverSideTranslations} from 'next-i18next/serverSideTranslations';

import Layout from '../../components/Layout';
import AuthorForm, {FormFields} from '../../components/Author/Form';

import {useCreateAuthor} from '../../service-hooks/resourceAuthor';

type InitialProps = Promise<{
  namespacesRequired: string[];
}>;

type Props = {
  t: TFunction;
  i18n: I18n;
};

// 按照文档,这个函数应该和getStaticProps作用类似
async function getLocale({locale}) {
  return {
    ...(await serverSideTranslations(locale, ['common', 'form', 'admin', 'resource-types'])),
    // 传递给页面组件的props
  };
}

// 因为异步函数报错,所以移除了类型
const NewAuthor = async () => {
  const {t, i18n} = useTranslation(['common', 'form', 'admin', 'resource-types']);
  const router = useRouter();
  const {mutate: create, isLoading} = useCreateAuthor();

  return (
    <Layout defaultLanguage={i18n.language} tFunc={t}>
      <NextSeo title={t('form:new', {entity: t('admin:authors.label')})}/>
      <div className="pt-4">
        <AuthorForm tFunc={t} processLoading={isLoading} texts={AuthorFormTexts} onFinish={handleFinish}/>
      </div>
    </Layout>
  );
};

export default NewAuthor;

解决方案

App Router中获取locale的逻辑和Pages路由完全不同,需要结合服务器组件特性和国际化配置来实现,同时适配next-i18next的翻译加载:

1. 服务器组件中获取locale(推荐方案)

App Router的页面默认是服务器组件,可以直接从路由参数params中获取locale(前提是已配置国际化路由),并在服务器端预加载翻译:

import React from 'react';
import {NextSeo} from 'next-seo';
import {serverSideTranslations} from 'next-i18next/serverSideTranslations';

import Layout from '../../components/Layout';
import AuthorClientComponent from './AuthorClientComponent';

// 服务器组件接收路由params
async function NewAuthor({params}: { params: { locale: string } }) {
  // 在服务器端预加载对应locale的翻译
  const {t, i18n} = await serverSideTranslations(params.locale, ['common', 'form', 'admin', 'resource-types']);

  return (
    <Layout defaultLanguage={i18n.language} tFunc={t}>
      <NextSeo title={t('form:new', {entity: t('admin:authors.label')})}/>
      <div className="pt-4">
        {/* 将需要客户端交互的逻辑抽离为客户端组件 */}
        <AuthorClientComponent t={t} locale={params.locale} />
      </div>
    </Layout>
  );
}

export default NewAuthor;

抽离的客户端组件(AuthorClientComponent.tsx)

'use client';
import React from 'react';
import {message} from 'antd';
import {useRouter} from 'next/navigation';
import AuthorForm, {FormFields} from '../../components/Author/Form';
import {useCreateAuthor} from '../../service-hooks/resourceAuthor';

type Props = {
  t: any;
  locale: string;
};

function AuthorClientComponent({t, locale}: Props) {
  const router = useRouter();
  const {mutate: create, isLoading} = useCreateAuthor();

  const handleFinish = async (values: FormFields) => {
    try {
      await create(values);
      message.success(t('common:success'));
      router.push(`/${locale}/admin/authors`);
    } catch (err) {
      message.error(t('common:error'));
    }
  };

  return (
    <AuthorForm tFunc={t} processLoading={isLoading} texts={AuthorFormTexts} onFinish={handleFinish}/>
  );
}

export default AuthorClientComponent;

2. 客户端组件中获取locale

如果需要在纯客户端组件中获取当前locale,可以使用useRouter钩子的locale属性:

'use client';
import {useRouter} from 'next/navigation';

function SomeClientComponent() {
  const router = useRouter();
  const currentLocale = router.locale; // 获取当前语言环境
  // ...后续逻辑
}

关键注意点

  • App Router不再支持getStaticProps,服务器组件可直接异步获取数据和翻译
  • serverSideTranslations必须在服务器组件中调用,不能在客户端组件使用
  • 包含客户端钩子(如useRouter、useMutation)的组件必须添加'use client'指令

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:30:58