Next.js 服务器端重定向覆盖区域设置

use*_*007 6 redirect internationalization next.js

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

主页/使用getServerSideProps并将用户重定向到配置文件或登录页面。为此,我执行以下操作:

    return {
      redirect: {
        permanent: false,
        destination: someLogic ? `${context.locale}/login` : `${context.locale}/profile`,
      },
    };
Run Code Online (Sandbox Code Playgroud)

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

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

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

我目前正在使用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,
  }
}
Run Code Online (Sandbox Code Playgroud)

小智 3

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

  • 将上下文传递给 getServerSideProps:
    export const getServerSideProps = async (context) => {
Run Code Online (Sandbox Code Playgroud)
  • 从上下文中获取区域设置:
    const { locale } = context;

Run Code Online (Sandbox Code Playgroud)
  • 使用模板文字将当前区域设置与所需目标连接起来:
    return {
                redirect: {
                destination: `/${locale}${getLoginPageUrl()}`,
                permanent: false,
            },
        };
Run Code Online (Sandbox Code Playgroud)

这是我的守卫的完整代码:

    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: {} };
        };
    }
Run Code Online (Sandbox Code Playgroud)

这是我如何使用它的示例:

    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,
            },
        };
    });
Run Code Online (Sandbox Code Playgroud)

请记住,如果您使用此防护,您的道具将位于data中,因此例如为了让我从页面中的先前代码访问 orderDetails ,必须执行以下操作:

    const OrderConfirmed = ({ data }) => (
        <OrderConfirmedPageWrapper orderDetails={data?.props?.orderDetails} />
    );
Run Code Online (Sandbox Code Playgroud)

我目前正在使用"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',
        },
Run Code Online (Sandbox Code Playgroud)