javascript - 如何在 Next.js 中重新加载时强制执行 i18n 语言环境 slug 并实现 i18n 一致性?

标签 javascript internationalization next.js

我正在使用 next-translate .默认情况下,我的路线被识别如下:

/about         <---
/de/about
/es/about
但我想强制执行 的语言环境全部 路径:
/en/about      <---
/de/about
/es/about
这是我的配置:
next.config.js
const nextTranslate = require('next-translate');

module.exports = nextTranslate({
    ...
    i18n: {
        localeDetection: false,
        locales: ['en', 'de', 'es'],
        defaultLocale: 'en',
    }
});
i18n.js
module.exports = {
    locales: ['en', 'de', 'es'],
    defaultLocale: 'en',
    pages: {
        '*': ['common']
    },
    interpolation: {
        prefix: '${',
        suffix: '}',
    },
    loadLocaleFrom: (locale, namespace) =>
        import(`./translations/${locale}/${namespace}`).then((m) => m.default),
}
请注意,我还有一个保留 NEXT_LOCALE 的 lang 更改组件。曲奇饼。因此,我希望当我访问 /about 时和我的NEXT_LOCALE cookie 之前已设置为 de ,路由器会将我重定向到 /de/about . 但它没有 .它停留在 /about并将 cookie 重写为 en ...
这是当前 pages文件夹结构:
...
pages/
  _app.tsx
  _document.tsx
  about.tsx
  ...
我需要把它改造成这个吗?
pages/
  _app.tsx
  _document.tsx
  [lang]/         <---
    about.tsx
    ...
如果是这样,下一步是什么?
  • 通过 useRouter() 解析首选语言环境
  • 解析NEXT_LOCALE cookies
  • 解析lang蛞蝓

  • 然后决定哪个优先级更高?我应该在哪里做?在 _app.tsx/一些HOC?
    我需要任何rewritesredirects在我的next.config.js或者我应该通过Router.push动态处理这些吗? ?

    最佳答案

    坚持 NEXT_LOCALE 的事实cookie 不会根据其值自动重定向是因为您已通过设置 localeDetection: false 显式禁用它.这会影响基于 header 的重定向以及基于 cookie 的重定向。
    只需将其从您的 next.config.js 中删除即可应该解决这个问题。

    没有内置方法可以在所有路径上强制使用默认语言环境。但是,有一些解决方法可以帮助在 URL 上添加默认语言环境的前缀。
    解决方法 #1:将默认语言环境设置为 default , 并在中间件中重定向
    i18n Routing 中所述文档,添加一个名为 default 的新“虚拟”语言环境并将其设置为默认语言环境。请注意,此语言环境实际上不会被使用,它只会让我们拥有 en语言环境总是以其路径为前缀。

    // next.config.js
    module.exports = {
        i18n: {
            locales: ['default', 'en', 'de', 'es'],
            defaultLocale: 'default'
        }
    }
    
    接下来,创建一个 _middleware文件重定向到 /en如果向 default 发出请求,则为前缀语言环境。
    // pages/_middleware.ts
    import { NextRequest, NextResponse } from 'next/server'
    
    const PUBLIC_FILE = /\.(.*)$/
    
    export function middleware(request: NextRequest) {
        const shouldHandleLocale = !PUBLIC_FILE.test(request.nextUrl.pathname)
            && !request.nextUrl.pathname.includes('/api/') 
            && request.nextUrl.locale === 'default'
    
        if (shouldHandleLocale) {
            const url = request.nextUrl.clone()
            url.pathname = `/en${request.nextUrl.pathname}`
            return NextResponse.redirect(url)
        }
    
        return undefined
    }
    
    解决方法 #2:浅路由到客户端的前缀路径
    或者,您可以检查默认语言环境并在首次安装时通过 router.push 在 URL 中显式设置它。 .
    让我们假设以下自定义 useDefaultLocale抽象要重用的逻辑的钩子(Hook)。
    import { useState, useEffect } from 'react';
    import { useRouter } from 'next/router';
    
    export const useDefaultLocale = () => {
        const router = useRouter();
    
        useEffect(() => {
            if (router.locale === router.defaultLocale) {
                router.push(`/${router.locale}${router.asPath}`, undefined, {
                    locale: false,
                    shallow: true // Optionally add this if you don't want to rerun data fetching methods
                });
            }
        }, [router.asPath]);
    };
    
    然后可以在您的页面或 _app.js 中使用.
    import { useDefaultLocale } from '<path-to>/use-default-locale';
    
    const AboutPage = () => {
        useDefaultLocale()
    
        return <>About Page</>;
    };
    

    关于javascript - 如何在 Next.js 中重新加载时强制执行 i18n 语言环境 slug 并实现 i18n 一致性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67149545/

    相关文章:

    reactjs - react-bootstrap + purgeCss + next.js

    css - 为什么设置了 dialogClassName 和使用 Styled JSX 的 Bootstrap 模态样式需要全局标记?

    javascript - 无法将 undefined 或 null 转换为对象 redux

    javascript - 如何在 yii2 中使用 php jquery?

    javascript - 摇摇欲坠的比例动画

    ios - 如何强制 NSLocalizedString 使用特定语言

    c# - 如何从同一个 XLIFF 翻译文件生成 .resx 和 .properties 文件

    php - Doctrine2 中是否有 i18n 解决方案

    next.js - 节点模块中未定义错误导航器

    javascript - 是否可以在 Javascript 的选择选项上附加商品数量?