【问题标题】:Next.js server side redirection overrides the localeNext.js 服务器端重定向覆盖了语言环境
【发布时间】:2021-06-22 05:02:45
【问题描述】:

在我的一些页面中,我使用getServerSideProps 进行 API 调用并在必要时重定向用户。我正在构建的网络应用程序是多语言的,我需要始终向用户显示正确的语言。

主页/ 使用getServerSideProps 并将用户重定向到个人资料或登录页面。为此,我执行以下操作:

    return {
      redirect: {
        permanent: false,
        destination: someLogic ? `${context.locale}/login` : `${context.locale}/profile`,
      },
    };

现在配置文件和用户页面也使用getServerSideProps,以检查是否存在有效会话并在必要时重定向用户。例如,当他的会话过期时,用户将尝试访问个人资料页面,然后他将被重定向到登录页面。如果我将destination 属性设置为/login,语言环境属性将被覆盖,用户将获得默认语言并被重定向到domain/login。如果我将它设置为${context.locale}/login,并且最初调用的页面是domain/fr-FR/profile,那么用户将被重定向到domain/fr-FR/fr-FR/login

使用router.pushrouter.replace 进行客户端重定向工作正常并返回正确的网址。

据我了解,我无法从 getServerSideProps 的上下文中获取绝对 URL 来检查区域设置是否已设置,我该如何解决这个问题?

我目前正在使用next 10.0.4,这是我的next.config.js

module.exports = {
  i18n: {
    locales: ['de-DE', 'en-US', 'fr-FR', 'nl-NL', 'it-IT'],
    defaultLocale: 'en-US',
    localDetection: true,
  }
}

【问题讨论】:

    标签: redirect internationalization next.js


    【解决方案1】:

    我遇到了同样的问题,并按照以下步骤解决了:

    • 将上下文传递给 getServerSideProps:
        export const getServerSideProps = async (context) => {
    
    • 从上下文中获取语言环境:
        const { locale } = context;
    
    
    • 使用模板文字将当前语言环境与所需目的地连接起来:
        return {
                    redirect: {
                    destination: `/${locale}${getLoginPageUrl()}`,
                    permanent: false,
                },
            };
    

    这是我的守卫的全部代码:

        export function withAuthServerSideProps(getServerSidePropsFunc) {
            return async (context) => {
                const {
                    req: { cookies },
                    query: { city },
                    locale,
                } = context;
        
                if (!cookies.userToken) {
                    return {
                        redirect: {
                            destination: `/${locale}${getLoginPageUrl(city ? city : '')}`,
                            permanent: false,
                        },
                    };
                }
                if (getServerSidePropsFunc) {
                    return { props: { data: await getServerSidePropsFunc(context) } };
                }
                return { props: {} };
            };
        }
    

    以下是我如何使用它的示例:

        export const getServerSideProps = withAuthServerSideProps(async (context) => {
            const res = await ProductsService.fetchOrderDetails({
                    id: 'b324015f-bf3f-4862-9817-61b954278168',
                });
        
            if (!res.data) {
                return {
                    notFound: true,
                };
            }
        
            return {
                props: {
                    orderDetails: res.data,
                },
            };
        });
    

    请记住,如果您使用此守卫,您的道具将在 data 中,例如,为了让我从之前的代码中访问 orderDetails我的页面我必须进行以下操作:

        const OrderConfirmed = ({ data }) => (
            <OrderConfirmedPageWrapper orderDetails={data?.props?.orderDetails} />
        );
    

    我目前正在使用"next": "10.0.6",这是我的next.config.js

        i18n: {
                locales: [
                    'en-kw',
                    'ar-kw',
                    'en-sa',
                    'ar-sa',
                    'en-qa',
                    'ar-qa',
                    'en-bh',
                    'ar-bh',
                    'en-ae',
                    'ar-ae',
                    'en-gb',
                    'ar-gb',
                    'catchAll',
                ],
                defaultLocale: 'catchAll',
            },
    

    【讨论】:

      【解决方案2】:

      语言环境被应用了两次,因为您设置的目标路径没有前导 /。只需在开头添加 / 即可解决您的问题。

      return {
          redirect: {
              permanent: false,
              destination: someLogic ? `/${context.locale}/login` : `/${context.locale}/profile`
              //                        ^                            ^
          }
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-10
        • 2018-09-01
        • 2021-04-02
        相关资源
        最近更新 更多